diff --git a/build.gradle b/build.gradle index b3f35803..62b509c4 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ apply plugin: 'maven-publish' allprojects { group = 'com.wizardlybump17.wlib' - version = '1.6.7' + version = '1.7.0' apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'java' diff --git a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandExecutor.java b/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandExecutor.java index 57ed1875..743da1c2 100644 --- a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandExecutor.java +++ b/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandExecutor.java @@ -1,13 +1,13 @@ package com.wizardlybump17.wlib.bungee.command; -import com.wizardlybump17.wlib.bungee.command.sender.GenericSender; -import com.wizardlybump17.wlib.bungee.command.sender.ProxiedPlayerSender; +import com.wizardlybump17.wlib.bungee.command.sender.CommandSender; import com.wizardlybump17.wlib.command.CommandManager; -import com.wizardlybump17.wlib.command.CommandSender; +import com.wizardlybump17.wlib.command.exception.CommandException; import com.wizardlybump17.wlib.command.holder.CommandExecutor; -import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.plugin.Command; +import java.util.logging.Level; + public class BungeeCommandExecutor extends Command implements CommandExecutor { private final CommandManager manager; @@ -18,17 +18,16 @@ public BungeeCommandExecutor(CommandManager manager, String name) { } @Override - public void execute(CommandSender sender, String commandName, String[] args) { + public void execute(com.wizardlybump17.wlib.command.CommandSender sender, String commandName, String[] args) throws CommandException { manager.execute(sender, commandName + " " + String.join(" ", args)); } @Override public void execute(net.md_5.bungee.api.CommandSender sender, String[] args) { - CommandSender realSender; - if (sender instanceof ProxiedPlayer) - realSender = new ProxiedPlayerSender((ProxiedPlayer) sender); - else - realSender = new GenericSender(sender); - execute(realSender, getName(), args); + try { + execute(new CommandSender(sender), getName(), args); + } catch (CommandException e) { + manager.getHolder().getLogger().log(Level.SEVERE, "Error while executing a command", e); + } } } diff --git a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandManager.java b/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandManager.java index 48c0b047..416de0ef 100644 --- a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandManager.java +++ b/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/BungeeCommandManager.java @@ -1,7 +1,7 @@ package com.wizardlybump17.wlib.bungee.command; import com.wizardlybump17.wlib.command.CommandManager; -import com.wizardlybump17.wlib.command.RegisteredCommand; +import com.wizardlybump17.wlib.command.registered.RegisteredCommand; import net.md_5.bungee.api.plugin.Command; import net.md_5.bungee.api.plugin.Plugin; diff --git a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/GenericSender.java b/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/CommandSender.java similarity index 64% rename from bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/GenericSender.java rename to bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/CommandSender.java index 86698b06..ef0ddda4 100644 --- a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/GenericSender.java +++ b/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/CommandSender.java @@ -1,11 +1,13 @@ package com.wizardlybump17.wlib.bungee.command.sender; -import com.wizardlybump17.wlib.command.CommandSender; import lombok.RequiredArgsConstructor; import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ConnectedPlayer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import org.jetbrains.annotations.NotNull; @RequiredArgsConstructor -public class GenericSender implements CommandSender { +public class CommandSender implements com.wizardlybump17.wlib.command.CommandSender { private final net.md_5.bungee.api.CommandSender handle; @@ -34,12 +36,11 @@ public boolean hasPermission(String permission) { return handle.hasPermission(permission); } - @Override - public GenericSender toGeneric() { - return this; + public @NotNull ProxiedPlayer asProxiedPlayer() { + return (ProxiedPlayer) handle; } - public static boolean isGeneric() { - return true; + public @NotNull ConnectedPlayer asConnectedPlayer() { + return (ConnectedPlayer) handle; } } diff --git a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/ProxiedPlayerSender.java b/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/ProxiedPlayerSender.java deleted file mode 100644 index d2fca3f7..00000000 --- a/bungee/src/main/java/com/wizardlybump17/wlib/bungee/command/sender/ProxiedPlayerSender.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.wizardlybump17.wlib.bungee.command.sender; - -import com.wizardlybump17.wlib.command.CommandSender; -import lombok.RequiredArgsConstructor; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.connection.ProxiedPlayer; - -@RequiredArgsConstructor -public class ProxiedPlayerSender implements CommandSender { - - private final ProxiedPlayer handle; - - @Override - public ProxiedPlayer getHandle() { - return handle; - } - - @Override - public void sendMessage(String message) { - handle.sendMessage(TextComponent.fromLegacyText(message)); - } - - @Override - public void sendMessage(String... messages) { - handle.sendMessage(TextComponent.fromLegacyText(String.join("\n", messages))); - } - - @Override - public String getName() { - return handle.getName(); - } - - @Override - public boolean hasPermission(String permission) { - return handle.hasPermission(permission); - } - - @Override - public GenericSender toGeneric() { - return new GenericSender(handle); - } -} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/CommandManager.java b/commands/src/main/java/com/wizardlybump17/wlib/command/CommandManager.java index 371354f6..6f8509a9 100644 --- a/commands/src/main/java/com/wizardlybump17/wlib/command/CommandManager.java +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/CommandManager.java @@ -1,59 +1,37 @@ package com.wizardlybump17.wlib.command; +import com.wizardlybump17.wlib.command.data.CommandData; +import com.wizardlybump17.wlib.command.exception.CommandException; +import com.wizardlybump17.wlib.command.extractor.CommandExtractor; +import com.wizardlybump17.wlib.command.extractor.DirectCommandExtractor; +import com.wizardlybump17.wlib.command.extractor.MethodCommandExtractor; import com.wizardlybump17.wlib.command.holder.CommandHolder; -import com.wizardlybump17.wlib.util.ReflectionUtil; +import com.wizardlybump17.wlib.command.registered.RegisteredCommand; import lombok.Getter; import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; +import java.util.*; @Getter -@RequiredArgsConstructor public class CommandManager { private final List commands = new ArrayList<>(); protected final CommandHolder holder; private final @NonNull Map, Map> fieldCache = new HashMap<>(); + private final @NotNull Set commandExtractors = new HashSet<>(); - public void registerCommands(Object... objects) { - for (Object object : objects) { - for (Method method : object.getClass().getDeclaredMethods()) { - if (!method.isAnnotationPresent(Command.class) || method.getParameterCount() == 0 || !CommandSender.class.isAssignableFrom(method.getParameterTypes()[0])) - continue; - - MethodHandle handle; - try { - handle = MethodHandles.publicLookup().findVirtual(object.getClass(), method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes())); - } catch (NoSuchMethodException | IllegalAccessException e) { - holder.getLogger().log(Level.SEVERE, "Error while trying to get the MethodHandle for " + method.getName() + " at " + object.getClass().getName(), e); - continue; - } - - RegisteredCommand command = new RegisteredCommand( - method.getAnnotation(Command.class), - object, - method, - handle - ); - - commands.add(command); - com.wizardlybump17.wlib.command.holder.Command holderCommand = holder.getCommand(command.getName()); - if (holderCommand != null) - holderCommand.setExecutor(holderCommand.getDefaultExecutor(this, command.getName())); - } - } + public CommandManager(@NotNull CommandHolder holder) { + this.holder = holder; + commandExtractors.add(new MethodCommandExtractor()); + commandExtractors.add(new DirectCommandExtractor()); + } + public void registerCommands(Object... objects) { + for (Object object : objects) + for (CommandExtractor extractor : commandExtractors) + commands.addAll(extractor.extract(this, holder, object)); commands.sort(null); } @@ -61,22 +39,26 @@ public void unregisterCommands() { commands.clear(); } - public void execute(CommandSender sender, String string) { + public void execute(CommandSender sender, String string) throws CommandException { if (commands.isEmpty()) return; for (RegisteredCommand registeredCommand : commands) { - Command command = registeredCommand.getCommand(); + CommandData command = registeredCommand.getCommand(); CommandResult result = registeredCommand.execute(sender, string); switch (result) { case PERMISSION_FAIL -> { - handleMessage(registeredCommand, sender, command.permissionMessage(), command.permissionMessageIsField()); + String message = command.getPermissionMessage(); + if (message != null) + sender.sendMessage(message); return; } case INVALID_SENDER -> { - handleMessage(registeredCommand, sender, command.invalidSenderMessage(), command.invalidSenderMessageIsField()); + String message = command.getInvalidSenderMessage(); + if (message != null) + sender.sendMessage(message); return; } @@ -87,40 +69,9 @@ public void execute(CommandSender sender, String string) { } } - protected void handleMessage(@NonNull RegisteredCommand registeredCommand, @NonNull CommandSender sender, @NonNull String message, boolean isField) { - if (!isField) { - if (!message.isEmpty()) - sender.sendMessage(message); - return; - } - - String fieldMessage = getFieldMessage(registeredCommand, message); - if (fieldMessage != null) - sender.sendMessage(fieldMessage); - } - - protected @Nullable String getFieldMessage(@NonNull RegisteredCommand registeredCommand, @NonNull String fieldName) { - Map fields = fieldCache.computeIfAbsent(registeredCommand.getObject().getClass(), clazz -> { - Map map = new HashMap<>(); - for (Field field : clazz.getDeclaredFields()) - map.put(field.getName(), field); - return map; - }); - - Field field = fields.get(fieldName); - if (field == null) - return null; - - Object fieldValue = ReflectionUtil.getFieldValue(field, registeredCommand.getObject()); - return fieldValue == null ? null : fieldValue.toString(); - } - @NonNull public List<@NonNull String> autoComplete(@NonNull CommandSender sender, @NonNull String string) { - List result = new ArrayList<>(); - for (RegisteredCommand command : commands) - result.addAll(command.autoComplete(sender, string)); - return result; + return List.of(); } public List getCommand(String name) { @@ -131,10 +82,10 @@ public List getCommand(String name) { return commands; } - public List getCommands(Object object) { + public List getCommands(@NotNull Object object) { List commands = new ArrayList<>(this.commands.size()); for (RegisteredCommand command : this.commands) - if (command.getObject() == object) + if (command.isOwnedBy(object)) commands.add(command); return commands; } diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/CommandSender.java b/commands/src/main/java/com/wizardlybump17/wlib/command/CommandSender.java index c4b89aa3..127a3037 100644 --- a/commands/src/main/java/com/wizardlybump17/wlib/command/CommandSender.java +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/CommandSender.java @@ -1,7 +1,5 @@ package com.wizardlybump17.wlib.command; -import org.jetbrains.annotations.Nullable; - /** * Represents a command sender, someone that can trigger commands. * @@ -21,14 +19,4 @@ public interface CommandSender { String getName(); boolean hasPermission(String permission); - - /** - * Used to convert this CommandSender to a generic sender, a command sender that can be anything - * - * @return the generic sender - */ - @Nullable - default CommandSender toGeneric() { - return null; - } } diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/RegisteredCommand.java b/commands/src/main/java/com/wizardlybump17/wlib/command/RegisteredCommand.java deleted file mode 100644 index 5ae2885e..00000000 --- a/commands/src/main/java/com/wizardlybump17/wlib/command/RegisteredCommand.java +++ /dev/null @@ -1,275 +0,0 @@ -package com.wizardlybump17.wlib.command; - -import com.wizardlybump17.wlib.command.args.ArgsNode; -import com.wizardlybump17.wlib.command.args.ArgsReaderRegistry; -import com.wizardlybump17.wlib.command.args.ArgsReaderType; -import com.wizardlybump17.wlib.command.args.reader.ArgsReader; -import com.wizardlybump17.wlib.command.args.reader.ArgsReaderException; -import com.wizardlybump17.wlib.object.Pair; -import lombok.Getter; -import lombok.NonNull; -import org.jetbrains.annotations.NotNull; - -import java.lang.invoke.MethodHandle; -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.util.*; - -@Getter -public class RegisteredCommand implements Comparable { - - private final Command command; - private final Object object; - private final Method method; - private final List nodes = new ArrayList<>(); - private final @NonNull MethodHandle methodHandle; - - public RegisteredCommand(Command command, Object object, Method method, @NonNull MethodHandle methodHandle) { - this.command = command; - this.object = object; - this.method = method; - this.methodHandle = methodHandle; - prepareNodes(); - } - - private void prepareNodes() { - String[] commandArgs = command.execution().split(" "); - - Class[] types = method.getParameterTypes(); - Parameter[] parameters = method.getParameters(); - int index = 1; //skipping the first type because of the CommandSender - for (String commandArg : commandArgs) { - if (!requiredArgs(commandArg)) { - nodes.add(new ArgsNode( - commandArg, - false, - null, - null, - false - )); - continue; - } - - Description description = parameters[index].getAnnotation(Description.class); - - ArgsReaderType argsReaderType = parameters[index].getAnnotation(ArgsReaderType.class); - if (argsReaderType == null && Argument.class.isAssignableFrom(types[index])) - throw new IllegalArgumentException("the \"" + commandArg + "\" argument requires the " + ArgsReaderType.class.getName() + " annotation"); - - ArgsReader reader; - if (argsReaderType == null) - reader = ArgsReaderRegistry.INSTANCE.getReader(types[index]); - else - reader = ArgsReaderRegistry.INSTANCE.get(argsReaderType.value()); - if (reader == null) - throw new IllegalArgumentException("no reader found for " + types[index].getName()); - - nodes.add(new ArgsNode( - trim(commandArg), - true, - reader, - description == null ? null : description.value(), - Argument.class.isAssignableFrom(types[index]) - )); - - index++; - } - } - - public String getName() { - return command.execution().split(" ")[0]; - } - - @Override - public int compareTo(@NotNull RegisteredCommand o) { - if (o.command.priority() == -1 && command.priority() == -1) { - int args = compareArgs(o); - - if (args == 0) - return compareSize(o); - - return args; - } - - return Integer.compare(o.command.priority(), command.priority()); - } - - private int compareArgs(RegisteredCommand other) { - return Integer.compare(other.command.execution().split(" ").length, command.execution().split(" ").length); - } - - private int compareSize(RegisteredCommand other) { - return Integer.compare(other.command.execution().length(), command.execution().length()); - } - - public Optional>> parse(String input, boolean autoComplete) throws ArgsReaderException { - List toParse = new ArrayList<>(); - checkArrays(input, toParse, autoComplete); - - List> result = new ArrayList<>(nodes.size()); - - if (parseRequiredOnly(result, toParse, autoComplete)) - return Optional.of(result); - - return Optional.empty(); - } - - private boolean parseRequiredOnly(List> target, List strings, boolean autoComplete) throws ArgsReaderException { - if (autoComplete && nodes.size() > strings.size()) - return false; - - for (int i = 0; i < nodes.size() && i < strings.size(); i++) { - ArgsNode node = nodes.get(i); - if (!node.isUserInput()) { - if (!node.getName().equalsIgnoreCase(strings.get(i))) - return false; - - continue; - } - - Object parse = node.parse(strings.get(i)); - if (parse == ArgsNode.EMPTY) - continue; - - target.add(new Pair<>(node, parse)); - } - - return true; - } - - private void checkArrays(String input, List target, boolean autoComplete) throws ArgsReaderException { - StringBuilder builder = new StringBuilder(); - boolean inArray = false; - for (String s : input.split(" ")) { - if (s.startsWith("\"") && s.endsWith("\"") && !s.endsWith("\\\"") && s.length() != 1) { //"string" | single word - target.add(s.substring(1, s.length() - 1)); - continue; - } - - if (s.startsWith("\"")) { //"string | it is starting the array - builder.append(s.substring(1).replace("\\\"", "\"")).append(" "); - inArray = true; - continue; - } - - if (s.endsWith("\"") && !s.endsWith("\\\"")) { //string" | it is ending the array - builder.append(s.replace("\\\"", "\""), 0, s.length() - 1); - target.add(builder.toString()); - builder = new StringBuilder(); - inArray = false; - continue; - } - - if (!builder.isEmpty()) { //string | it is in the array - builder.append(s.replace("\\\"", "\"")).append(" "); - continue; - } - - target.add(s.replace("\\\"", "\"")); //string | it is not in the array - } - - if (inArray && !autoComplete) - throw new ArgsReaderException("Invalid array"); - } - - public CommandResult execute(CommandSender sender, String string) { - try { - Optional>> parse = parse(string, true); - if (parse.isEmpty()) - return CommandResult.ARGS_FAIL; - - if (!getSenderType().isInstance(sender) && !isSenderGeneric()) - return CommandResult.INVALID_SENDER; - - Object[] objects = parse.get().stream().map(Pair::getSecond).toArray(); - return executeInternal(sender, objects); - } catch (ArgsReaderException e) { - return CommandResult.EXCEPTION; - } - } - - private CommandResult executeInternal(CommandSender sender, Object[] objects) { - try { - if (!command.permission().isEmpty() && !sender.hasPermission(command.permission())) - return CommandResult.PERMISSION_FAIL; - - List list = new ArrayList<>(Arrays.asList(objects)); - list.add(0, isSenderGeneric() ? sender.toGeneric() : sender); - - if (list.size() != method.getParameterCount()) - return CommandResult.ARGS_FAIL; - - list.add(0, object); - methodHandle.invokeWithArguments(list); - return CommandResult.SUCCESS; - } catch (Throwable e) { - e.printStackTrace(); - return CommandResult.METHOD_FAIL; - } - } - - @NonNull - public List<@NonNull String> autoComplete(@NonNull CommandSender sender, @NonNull String string) { - if (nodes.size() == 1) - return Collections.emptyList(); - - if (!getSenderType().isInstance(sender) && !isSenderGeneric()) - return Collections.emptyList(); - - try { - Optional>> parse = parse(string, false); - if (parse.isEmpty()) - return Collections.emptyList(); - - String[] split = string.split(" "); - String lastString = split[split.length - 1]; - - List> pairs = parse.get(); - - if (pairs.isEmpty()) { - ArgsNode secondNode = nodes.get(1); - ArgsReader secondNodeReader = secondNode.getReader(); - return secondNodeReader == null ? List.of(secondNode.getName()) : secondNodeReader.autoComplete(sender, lastString); - } - - Pair lastPair = pairs.get(pairs.size() - 1); - - ArgsNode node = lastPair.getFirst(); - ArgsReader reader = node.getReader(); - - return reader == null ? List.of(node.getName()) : reader.autoComplete(sender, lastString); - } catch (ArgsReaderException e) { - e.printStackTrace(); - return Collections.emptyList(); - } - } - - @Override - public String toString() { - return "RegisteredCommand{" + command.execution() + "}"; - } - - @SuppressWarnings("unchecked") - public Class> getSenderType() { - return (Class>) method.getParameterTypes()[0]; - } - - public boolean isSenderGeneric() { - boolean result = false; - try { - result = (Boolean) getSenderType().getDeclaredMethod("isGeneric").invoke(null); - } catch (NoSuchMethodException ignored) { - } catch (Exception e) { - e.printStackTrace(); - } - return result; - } - - private static String trim(String string) { - return string.substring(1, string.length() - 1); - } - - private static boolean requiredArgs(String string) { - return string.startsWith("<") && string.endsWith(">"); - } -} \ No newline at end of file diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/Command.java b/commands/src/main/java/com/wizardlybump17/wlib/command/annotation/Command.java similarity index 96% rename from commands/src/main/java/com/wizardlybump17/wlib/command/Command.java rename to commands/src/main/java/com/wizardlybump17/wlib/command/annotation/Command.java index ca53cf22..1009d78b 100644 --- a/commands/src/main/java/com/wizardlybump17/wlib/command/Command.java +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/annotation/Command.java @@ -1,4 +1,6 @@ -package com.wizardlybump17.wlib.command; +package com.wizardlybump17.wlib.command.annotation; + +import com.wizardlybump17.wlib.command.CommandSender; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/data/AnnotationCommandData.java b/commands/src/main/java/com/wizardlybump17/wlib/command/data/AnnotationCommandData.java new file mode 100644 index 00000000..b659ea2e --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/data/AnnotationCommandData.java @@ -0,0 +1,96 @@ +package com.wizardlybump17.wlib.command.data; + +import com.wizardlybump17.wlib.command.annotation.Command; +import com.wizardlybump17.wlib.util.ReflectionUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class AnnotationCommandData implements CommandData { + + private final @NotNull Command annotation; + private final @NotNull Object object; + private final @NotNull Map fieldCache = new HashMap<>(); + + public AnnotationCommandData(@NotNull Command annotation, @NotNull Object object) { + this.annotation = annotation; + this.object = object; + } + + @Override + public @NotNull String getExecution() { + return annotation.execution(); + } + + @Override + public @Nullable String getPermission() { + String permission = annotation.permission(); + return permission.isBlank() ? CommandData.super.getPermission() : permission; + } + + @Override + public @Nullable String getPermissionMessage() { + return getMessage(annotation.permissionMessage(), annotation.permissionMessageIsField(), CommandData.super.getPermissionMessage()); + } + + @Override + public int getPriority() { + int priority = annotation.priority(); + return priority == -1 ? CommandData.super.getPriority() : priority; + } + + @Override + public @Nullable String getDescription() { + String description = annotation.description(); + return description.isBlank() ? CommandData.super.getDescription() : description; + } + + @Override + public @Nullable String getInvalidSenderMessage() { + return getMessage(annotation.invalidSenderMessage(), annotation.invalidSenderMessageIsField(), CommandData.super.getInvalidSenderMessage()); + } + + protected @Nullable String getMessage(@NotNull String message, boolean isField, @Nullable String defaultMessage) { + if (isField) { + return ReflectionUtil.getFieldValue( + fieldCache.computeIfAbsent( + message, + $ -> ReflectionUtil.getField(message, object.getClass()) + ), + object + ); + } + return message.isBlank() ? defaultMessage : message; + } + + public @NotNull Command getAnnotation() { + return annotation; + } + + + @Override + public boolean equals(Object object1) { + if (object1 == null || getClass() != object1.getClass()) + return false; + AnnotationCommandData that = (AnnotationCommandData) object1; + return Objects.equals(annotation, that.annotation) && Objects.equals(object, that.object) && Objects.equals(fieldCache, that.fieldCache); + } + + @Override + public int hashCode() { + return Objects.hash(annotation, object, fieldCache); + } + + @Override + public String toString() { + return "AnnotationCommandData{" + + "annotation=" + annotation + + ", object=" + object + + ", fieldCache=" + fieldCache + + '}'; + } +} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/data/CommandData.java b/commands/src/main/java/com/wizardlybump17/wlib/command/data/CommandData.java new file mode 100644 index 00000000..9c077a5d --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/data/CommandData.java @@ -0,0 +1,66 @@ +package com.wizardlybump17.wlib.command.data; + +import com.wizardlybump17.wlib.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface CommandData { + + /** + *

How the sender must type the command in order for it to be triggered. + * Example:

command hello world
+ * In the example above, the sender must type /command hello world, so it can be triggered. + * To add parameters that depends on the sender input, just put the parameter between <>. + *
+ * Example:
command <hello> world

+ *

The type of each parameter is defined in the method that have this annotation. + * An example for the command above: + *

+     *  @Command(execution = "command <hello> world")
+     *  public void commandHelloWorld(GenericSender sender, String hello) {
+     *      System.out.println(sender.getName() + " executed the hello world command with the argument " + hello);
+     *  }
+     * 

+ * + * @return how the command must be sent to be triggered + * @see com.wizardlybump17.wlib.command.args.reader.ArgsReader + */ + @NotNull String getExecution(); + + /** + * @return which permission the sender must have to trigger this command + */ + default @Nullable String getPermission() { + return null; + } + + /** + *

Used when the {@link CommandSender} does not have the required {@link #getPermission()}.

+ * @return the message to be sent when the {@link CommandSender} does not have the required {@link #getPermission()} + */ + default @Nullable String getPermissionMessage() { + return null; + } + + /** + * @return the priority of this command + */ + default int getPriority() { + return getExecution().split(" ").length; + } + + /** + * @return the description of this command + */ + default @Nullable String getDescription() { + return null; + } + + /** + *

Used when the {@link CommandSender} is not valid for this command.

+ * @return the message to be sent when the {@link CommandSender} is not valid for this command + */ + default @Nullable String getInvalidSenderMessage() { + return null; + } +} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/exception/CommandException.java b/commands/src/main/java/com/wizardlybump17/wlib/command/exception/CommandException.java new file mode 100644 index 00000000..7c99b73f --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/exception/CommandException.java @@ -0,0 +1,21 @@ +package com.wizardlybump17.wlib.command.exception; + +import org.jetbrains.annotations.NotNull; + +public class CommandException extends Exception { + + public CommandException() { + } + + public CommandException(@NotNull String message) { + super(message); + } + + public CommandException(@NotNull String message, @NotNull Throwable cause) { + super(message, cause); + } + + public CommandException(@NotNull Throwable cause) { + super(cause); + } +} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/executor/CommandExecutor.java b/commands/src/main/java/com/wizardlybump17/wlib/command/executor/CommandExecutor.java new file mode 100644 index 00000000..298f73b7 --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/executor/CommandExecutor.java @@ -0,0 +1,12 @@ +package com.wizardlybump17.wlib.command.executor; + +import com.wizardlybump17.wlib.command.CommandSender; +import com.wizardlybump17.wlib.command.exception.CommandException; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public interface CommandExecutor { + + void execute(@NotNull CommandSender sender, @NotNull Map args) throws CommandException; +} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/CommandExtractor.java b/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/CommandExtractor.java new file mode 100644 index 00000000..8f1d4373 --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/CommandExtractor.java @@ -0,0 +1,13 @@ +package com.wizardlybump17.wlib.command.extractor; + +import com.wizardlybump17.wlib.command.CommandManager; +import com.wizardlybump17.wlib.command.holder.CommandHolder; +import com.wizardlybump17.wlib.command.registered.RegisteredCommand; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface CommandExtractor { + + @NotNull List extract(@NotNull CommandManager manager, @NotNull CommandHolder holder, @NotNull Object object); +} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/DirectCommandExtractor.java b/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/DirectCommandExtractor.java new file mode 100644 index 00000000..bb21f6c5 --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/DirectCommandExtractor.java @@ -0,0 +1,16 @@ +package com.wizardlybump17.wlib.command.extractor; + +import com.wizardlybump17.wlib.command.CommandManager; +import com.wizardlybump17.wlib.command.holder.CommandHolder; +import com.wizardlybump17.wlib.command.registered.RegisteredCommand; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class DirectCommandExtractor implements CommandExtractor { + + @Override + public @NotNull List extract(@NotNull CommandManager manager, @NotNull CommandHolder holder, @NotNull Object object) { + return object instanceof RegisteredCommand command ? List.of(command) : List.of(); + } +} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/MethodCommandExtractor.java b/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/MethodCommandExtractor.java new file mode 100644 index 00000000..3e650e68 --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/extractor/MethodCommandExtractor.java @@ -0,0 +1,44 @@ +package com.wizardlybump17.wlib.command.extractor; + +import com.wizardlybump17.wlib.command.CommandManager; +import com.wizardlybump17.wlib.command.CommandSender; +import com.wizardlybump17.wlib.command.annotation.Command; +import com.wizardlybump17.wlib.command.holder.CommandHolder; +import com.wizardlybump17.wlib.command.registered.RegisteredCommand; +import com.wizardlybump17.wlib.command.registered.RegisteredMethodCommand; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +public class MethodCommandExtractor implements CommandExtractor { + + @Override + public @NotNull List extract(@NotNull CommandManager manager, @NotNull CommandHolder holder, @NotNull Object object) { + List commands = new ArrayList<>(); + for (Method method : object.getClass().getDeclaredMethods()) { + if (!method.isAnnotationPresent(Command.class) || method.getParameterCount() == 0 || !CommandSender.class.isAssignableFrom(method.getParameterTypes()[0])) + continue; + + RegisteredMethodCommand command; + try { + command = new RegisteredMethodCommand( + method.getAnnotation(Command.class), + object, + method + ); + } catch (Exception e) { + holder.getLogger().log(Level.SEVERE, "Error while creating a command", e); + continue; + } + + commands.add(command); + com.wizardlybump17.wlib.command.holder.Command holderCommand = holder.getCommand(command.getName()); + if (holderCommand != null) + holderCommand.setExecutor(holderCommand.getDefaultExecutor(manager, command.getName())); + } + return commands; + } +} diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/holder/CommandExecutor.java b/commands/src/main/java/com/wizardlybump17/wlib/command/holder/CommandExecutor.java index de8e1475..24bf890b 100644 --- a/commands/src/main/java/com/wizardlybump17/wlib/command/holder/CommandExecutor.java +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/holder/CommandExecutor.java @@ -2,11 +2,12 @@ import com.wizardlybump17.wlib.command.CommandSender; import com.wizardlybump17.wlib.command.args.reader.ArgsReaderException; +import com.wizardlybump17.wlib.command.exception.CommandException; /** * Interface for intercepting commands when they are called */ public interface CommandExecutor { - void execute(CommandSender sender, String commandName, String[] args) throws ArgsReaderException; + void execute(CommandSender sender, String commandName, String[] args) throws ArgsReaderException, CommandException; } diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/registered/RegisteredCommand.java b/commands/src/main/java/com/wizardlybump17/wlib/command/registered/RegisteredCommand.java new file mode 100644 index 00000000..3106237f --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/registered/RegisteredCommand.java @@ -0,0 +1,131 @@ +package com.wizardlybump17.wlib.command.registered; + +import com.wizardlybump17.wlib.command.CommandResult; +import com.wizardlybump17.wlib.command.CommandSender; +import com.wizardlybump17.wlib.command.args.ArgsNode; +import com.wizardlybump17.wlib.command.args.reader.ArgsReaderException; +import com.wizardlybump17.wlib.command.data.CommandData; +import com.wizardlybump17.wlib.command.exception.CommandException; +import com.wizardlybump17.wlib.command.executor.CommandExecutor; +import com.wizardlybump17.wlib.util.StringUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Optional; + +public class RegisteredCommand implements Comparable { + + private final @NotNull CommandData command; + private final @NotNull List nodes; + private final @NotNull CommandExecutor executor; + + public RegisteredCommand(@NotNull CommandData command, @NotNull List nodes, @NotNull CommandExecutor executor) { + this.command = command; + this.nodes = nodes; + this.executor = executor; + } + + public RegisteredCommand(@NotNull CommandData command, @NotNull List nodes) { + this.command = command; + this.nodes = nodes; + executor = createExecutor(); + } + + protected CommandExecutor createExecutor() { + throw new UnsupportedOperationException(); + } + + public String getName() { + return command.getExecution().split(" ")[0]; + } + + @Override + public int compareTo(@NotNull RegisteredCommand o) { + return Integer.compare(o.command.getPriority(), command.getPriority()); + } + + public Optional> parse(String input) throws ArgsReaderException { + List toParse = StringUtil.parseQuotedStrings(input); + + LinkedHashMap result = new LinkedHashMap<>(); + + if (checkNodes(result, toParse)) + return Optional.of(result); + + return Optional.empty(); + } + + protected boolean checkNodes(LinkedHashMap target, List strings) throws ArgsReaderException { + if (nodes.size() > strings.size()) + return false; + + for (int i = 0; i < nodes.size() && i < strings.size(); i++) { + ArgsNode node = nodes.get(i); + if (!node.isUserInput()) { + if (node.getName().equalsIgnoreCase(strings.get(i))) + continue; + return false; + } + + Object parse = node.parse(strings.get(i)); + if (parse != ArgsNode.EMPTY) + target.put(node.getName(), parse); + } + + return true; + } + + public @NotNull CommandResult execute(@NotNull CommandSender sender, @NotNull String string) throws CommandException { + if (!canExecute(sender)) + return CommandResult.INVALID_SENDER; + + String permission = command.getPermission(); + if (permission != null && !sender.hasPermission(permission)) + return CommandResult.PERMISSION_FAIL; + + try { + Optional> parse = parse(string); + if (parse.isEmpty()) + return CommandResult.ARGS_FAIL; + + LinkedHashMap args = parse.get(); + if (!isValidArgs(args)) + return CommandResult.ARGS_FAIL; + + executor.execute(sender, args); + return CommandResult.SUCCESS; + } catch (ArgsReaderException e) { + return CommandResult.EXCEPTION; + } + } + + protected boolean isValidArgs(@NotNull LinkedHashMap args) { + return true; + } + + public boolean canExecute(@NotNull CommandSender sender) { + return true; + } + + @Override + public String toString() { + return "RegisteredCommand{" + command.getExecution() + "}"; + } + + public @NotNull CommandData getCommand() { + return command; + } + + public @NotNull CommandExecutor getExecutor() { + return executor; + } + + public @NotNull List getNodes() { + return nodes; + } + + public boolean isOwnedBy(@NotNull Object object) { + return false; + } +} \ No newline at end of file diff --git a/commands/src/main/java/com/wizardlybump17/wlib/command/registered/RegisteredMethodCommand.java b/commands/src/main/java/com/wizardlybump17/wlib/command/registered/RegisteredMethodCommand.java new file mode 100644 index 00000000..5641650b --- /dev/null +++ b/commands/src/main/java/com/wizardlybump17/wlib/command/registered/RegisteredMethodCommand.java @@ -0,0 +1,123 @@ +package com.wizardlybump17.wlib.command.registered; + +import com.wizardlybump17.wlib.command.Argument; +import com.wizardlybump17.wlib.command.Description; +import com.wizardlybump17.wlib.command.annotation.Command; +import com.wizardlybump17.wlib.command.args.ArgsNode; +import com.wizardlybump17.wlib.command.args.ArgsReaderRegistry; +import com.wizardlybump17.wlib.command.args.ArgsReaderType; +import com.wizardlybump17.wlib.command.args.reader.ArgsReader; +import com.wizardlybump17.wlib.command.data.AnnotationCommandData; +import com.wizardlybump17.wlib.command.exception.CommandException; +import com.wizardlybump17.wlib.command.executor.CommandExecutor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +@Getter +public class RegisteredMethodCommand extends RegisteredCommand { + + private final @NotNull Command annotation; + private final @NotNull Object object; + private final @NotNull Method method; + private final @NotNull MethodHandle methodHandle; + + public RegisteredMethodCommand(@NotNull Command annotation, @NotNull Object object, @NotNull Method method) throws NoSuchMethodException, IllegalAccessException { + super( + new AnnotationCommandData( + annotation, + object + ), + new ArrayList<>() + ); + this.annotation = annotation; + this.object = object; + this.method = method; + methodHandle = MethodHandles.lookup().findVirtual(object.getClass(), method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes())); + prepareNodes(); + } + + @Override + protected CommandExecutor createExecutor() { + return (sender, args) -> { + List objects = new ArrayList<>(args.values()); + objects.add(0, object); + objects.add(1, sender); + try { + methodHandle.invokeWithArguments(objects); + } catch (Throwable e) { + throw new CommandException("Error while executing the command " + getCommand().getExecution() + " with the arguments " + args, e); + } + }; + } + + protected void prepareNodes() { + String[] commandArgs = getCommand().getExecution().split(" "); + + Class[] types = method.getParameterTypes(); + Parameter[] parameters = method.getParameters(); + int index = 1; //skipping the first type because of the CommandSender + for (String commandArg : commandArgs) { + if (!isRequiredArgs(commandArg)) { + getNodes().add(new ArgsNode( + commandArg, + false, + null, + null, + false + )); + continue; + } + + Description description = parameters[index].getAnnotation(Description.class); + + ArgsReaderType argsReaderType = parameters[index].getAnnotation(ArgsReaderType.class); + if (argsReaderType == null && Argument.class.isAssignableFrom(types[index])) + throw new IllegalArgumentException("the \"" + commandArg + "\" argument requires the " + ArgsReaderType.class.getName() + " annotation"); + + ArgsReader reader; + if (argsReaderType == null) + reader = ArgsReaderRegistry.INSTANCE.getReader(types[index]); + else + reader = ArgsReaderRegistry.INSTANCE.get(argsReaderType.value()); + if (reader == null) + throw new IllegalArgumentException("no reader found for " + types[index].getName()); + + getNodes().add(new ArgsNode( + trim(commandArg), + true, + reader, + description == null ? null : description.value(), + Argument.class.isAssignableFrom(types[index]) + )); + + index++; + } + } + + @Override + protected boolean isValidArgs(@NotNull LinkedHashMap args) { + return args.size() + 1 == method.getParameterCount(); + } + + @Override + public boolean isOwnedBy(@NotNull Object object) { + return this.object == object; + } + + private static String trim(String string) { + return string.substring(1, string.length() - 1); + } + + private static boolean isRequiredArgs(String string) { + return string.startsWith("<") && string.endsWith(">"); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/wizardlybump17/wlib/command/BukkitCommandExecutor.java b/core/src/main/java/com/wizardlybump17/wlib/command/BukkitCommandExecutor.java index c5577b03..c17fb0b0 100644 --- a/core/src/main/java/com/wizardlybump17/wlib/command/BukkitCommandExecutor.java +++ b/core/src/main/java/com/wizardlybump17/wlib/command/BukkitCommandExecutor.java @@ -1,54 +1,39 @@ package com.wizardlybump17.wlib.command; -import com.wizardlybump17.wlib.command.sender.ConsoleSender; -import com.wizardlybump17.wlib.command.sender.GenericSender; -import com.wizardlybump17.wlib.command.sender.PlayerSender; +import com.wizardlybump17.wlib.command.exception.CommandException; import lombok.RequiredArgsConstructor; -import lombok.SneakyThrows; import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.*; -import org.bukkit.entity.Player; +import org.bukkit.command.TabExecutor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.logging.Level; @RequiredArgsConstructor public class BukkitCommandExecutor implements TabExecutor, com.wizardlybump17.wlib.command.holder.CommandExecutor { private final CommandManager manager; - @SneakyThrows @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - execute(getSender(sender), command.getName(), args); + public boolean onCommand(@NotNull org.bukkit.command.CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + try { + execute(new com.wizardlybump17.wlib.command.sender.CommandSender(sender), command.getName(), args); + } catch (CommandException e) { + manager.getHolder().getLogger().log(Level.SEVERE, "Error while executing a command", e); + } return false; } @Override - public void execute(com.wizardlybump17.wlib.command.CommandSender sender, String commandName, String[] args) { + public void execute(com.wizardlybump17.wlib.command.CommandSender sender, String commandName, String[] args) throws CommandException { String commandExecution = commandName + " " + String.join(" ", args); manager.execute(sender, commandExecution); } @Nullable @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { -// String fullCommand = command.getName() + " " + String.join(" ", args); -// List suggestions = manager.autoComplete(getSender(sender), fullCommand); -// ArrayList strings = StringUtil.copyPartialMatches(args[args.length - 1], suggestions, new ArrayList<>(suggestions.size())); -// return strings; + public List onTabComplete(@NotNull org.bukkit.command.CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { return null; } - - private com.wizardlybump17.wlib.command.CommandSender getSender(CommandSender original) { - if (original instanceof Player player) - return new PlayerSender(player); - if (original instanceof ConsoleCommandSender consoleSender) - return new ConsoleSender(consoleSender); - if (original instanceof BlockCommandSender blockSender) - return new com.wizardlybump17.wlib.command.sender.BlockCommandSender(blockSender); - return new GenericSender(original); - } } diff --git a/core/src/main/java/com/wizardlybump17/wlib/command/sender/AbstractSender.java b/core/src/main/java/com/wizardlybump17/wlib/command/sender/AbstractSender.java deleted file mode 100644 index 98af7103..00000000 --- a/core/src/main/java/com/wizardlybump17/wlib/command/sender/AbstractSender.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.wizardlybump17.wlib.command.sender; - -import com.wizardlybump17.wlib.command.CommandSender; -import lombok.Getter; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -@Getter -public abstract class AbstractSender implements CommandSender { - - private final S handle; - - @Override - public void sendMessage(String message) { - handle.sendMessage(message); - } - - @Override - public void sendMessage(String... message) { - handle.sendMessage(String.join("\n", message)); - } - - @Override - public String getName() { - return handle.getName(); - } - - @Override - public boolean hasPermission(String permission) { - return handle.hasPermission(permission); - } - - @Override - @NonNull - public GenericSender toGeneric() { - return new GenericSender(handle); - } -} diff --git a/core/src/main/java/com/wizardlybump17/wlib/command/sender/BlockCommandSender.java b/core/src/main/java/com/wizardlybump17/wlib/command/sender/BlockCommandSender.java deleted file mode 100644 index 2f3b8455..00000000 --- a/core/src/main/java/com/wizardlybump17/wlib/command/sender/BlockCommandSender.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.wizardlybump17.wlib.command.sender; - -public class BlockCommandSender extends AbstractSender { - - public BlockCommandSender(org.bukkit.command.BlockCommandSender handle) { - super(handle); - } -} diff --git a/core/src/main/java/com/wizardlybump17/wlib/command/sender/CommandSender.java b/core/src/main/java/com/wizardlybump17/wlib/command/sender/CommandSender.java new file mode 100644 index 00000000..db06a313 --- /dev/null +++ b/core/src/main/java/com/wizardlybump17/wlib/command/sender/CommandSender.java @@ -0,0 +1,52 @@ +package com.wizardlybump17.wlib.command.sender; + +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public class CommandSender implements com.wizardlybump17.wlib.command.CommandSender { + + private final @NotNull org.bukkit.command.CommandSender handle; + + public CommandSender(@NotNull org.bukkit.command.CommandSender handle) { + this.handle = handle; + } + + @Override + public org.bukkit.command.CommandSender getHandle() { + return handle; + } + + @Override + public void sendMessage(String message) { + handle.sendMessage(message); + } + + @Override + public void sendMessage(String... message) { + handle.sendMessage(String.join("\n", message)); + } + + @Override + public String getName() { + return handle.getName(); + } + + @Override + public boolean hasPermission(String permission) { + return handle.hasPermission(permission); + } + + public @NotNull BlockCommandSender asBlockCommand() { + return (BlockCommandSender) handle; + } + + public @NotNull ConsoleCommandSender asConsole() { + return (ConsoleCommandSender) handle; + } + + public @NotNull Player asPlayer() { + return (Player) handle; + } +} diff --git a/core/src/main/java/com/wizardlybump17/wlib/command/sender/ConsoleSender.java b/core/src/main/java/com/wizardlybump17/wlib/command/sender/ConsoleSender.java deleted file mode 100644 index 46e55e01..00000000 --- a/core/src/main/java/com/wizardlybump17/wlib/command/sender/ConsoleSender.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.wizardlybump17.wlib.command.sender; - -import org.bukkit.command.ConsoleCommandSender; - -public class ConsoleSender extends AbstractSender { - - public ConsoleSender(ConsoleCommandSender handle) { - super(handle); - } -} diff --git a/core/src/main/java/com/wizardlybump17/wlib/command/sender/GenericSender.java b/core/src/main/java/com/wizardlybump17/wlib/command/sender/GenericSender.java deleted file mode 100644 index d223526d..00000000 --- a/core/src/main/java/com/wizardlybump17/wlib/command/sender/GenericSender.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.wizardlybump17.wlib.command.sender; - -import lombok.NonNull; -import org.bukkit.command.CommandSender; - -public class GenericSender extends AbstractSender { - - public GenericSender(CommandSender handle) { - super(handle); - } - - @Override - @NonNull - public GenericSender toGeneric() { - return this; - } - - public static boolean isGeneric() { - return true; - } -} diff --git a/core/src/main/java/com/wizardlybump17/wlib/command/sender/PlayerSender.java b/core/src/main/java/com/wizardlybump17/wlib/command/sender/PlayerSender.java deleted file mode 100644 index ac2f08eb..00000000 --- a/core/src/main/java/com/wizardlybump17/wlib/command/sender/PlayerSender.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.wizardlybump17.wlib.command.sender; - -import org.bukkit.entity.Player; - -public class PlayerSender extends AbstractSender { - - public PlayerSender(Player handle) { - super(handle); - } -}