From 00f18519b0b21b99d01fe330948ef1f8fe0588c2 Mon Sep 17 00:00:00 2001 From: Samuel Pizette Date: Sun, 4 Dec 2022 17:52:05 -0500 Subject: [PATCH] progress commit --- .../main/java/com/willfp/eco/core/Eco.java | 9 +- .../command/ArgumentAssertionException.java | 15 --- .../willfp/eco/core/command/CommandBase.java | 87 +++++++++-------- .../core/command/NotificationException.java | 15 +++ .../core/command/RegistrableCommandBase.java | 7 ++ .../eco/core/command/impl/PluginCommand.java | 15 ++- .../eco/core/command/impl/Subcommand.java | 39 +++----- .../eco/internal/command/EcoPluginCommand.kt | 93 +++++++++++++++++-- 8 files changed, 178 insertions(+), 102 deletions(-) delete mode 100644 eco-api/src/main/java/com/willfp/eco/core/command/ArgumentAssertionException.java create mode 100644 eco-api/src/main/java/com/willfp/eco/core/command/NotificationException.java create mode 100644 eco-api/src/main/java/com/willfp/eco/core/command/RegistrableCommandBase.java diff --git a/eco-api/src/main/java/com/willfp/eco/core/Eco.java b/eco-api/src/main/java/com/willfp/eco/core/Eco.java index f0e5e4ee..cc3cd60d 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/Eco.java +++ b/eco-api/src/main/java/com/willfp/eco/core/Eco.java @@ -1,6 +1,7 @@ package com.willfp.eco.core; import com.willfp.eco.core.command.CommandBase; +import com.willfp.eco.core.command.RegistrableCommandBase; import com.willfp.eco.core.command.impl.PluginCommand; import com.willfp.eco.core.config.ConfigType; import com.willfp.eco.core.config.interfaces.Config; @@ -169,10 +170,10 @@ public interface Eco { EcoPlugin getEcoPlugin(); @NotNull - CommandBase createPluginCommand(@NotNull EcoPlugin plugin, - @NotNull String name, - @NotNull String permission, - boolean playersOnly + RegistrableCommandBase createPluginCommand(@NotNull EcoPlugin plugin, + @NotNull String name, + @NotNull String permission, + boolean playersOnly ); @NotNull diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/ArgumentAssertionException.java b/eco-api/src/main/java/com/willfp/eco/core/command/ArgumentAssertionException.java deleted file mode 100644 index 0b7df97f..00000000 --- a/eco-api/src/main/java/com/willfp/eco/core/command/ArgumentAssertionException.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.willfp.eco.core.command; - -public class ArgumentAssertionException extends Exception { - - private final String langTarget; - - public ArgumentAssertionException(String langTarget) { - super(langTarget); - this.langTarget = langTarget; - } - - public String getLangTarget() { - return langTarget; - } -} diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java b/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java index 2b85fadd..06dfdd0b 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java +++ b/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java @@ -2,15 +2,17 @@ package com.willfp.eco.core.command; import com.google.common.collect.ImmutableList; import com.willfp.eco.core.EcoPlugin; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.function.Predicate; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; + /** * Interface for all command implementations. */ @@ -33,7 +35,7 @@ public interface CommandBase { * @return The description. */ @Nullable - default public String getDescription() { + default String getDescription() { return null; } @@ -64,7 +66,9 @@ public interface CommandBase { * @param command The subcommand. * @return The parent command. */ - CommandBase addSubcommand(@NotNull CommandBase command); + @NotNull CommandBase addSubcommand(@NotNull CommandBase command); + + @NotNull List getSubcommands(); /** * Handle command execution. @@ -73,7 +77,7 @@ public interface CommandBase { * @param args The args. */ default void onExecute(@NotNull CommandSender sender, - @NotNull List args) throws ArgumentAssertionException { + @NotNull List args) throws NotificationException { // Do nothing. } @@ -84,7 +88,7 @@ public interface CommandBase { * @param args The args. */ default void onExecute(@NotNull Player sender, - @NotNull List args) throws ArgumentAssertionException { + @NotNull List args) throws NotificationException { // Do nothing. } @@ -97,7 +101,7 @@ public interface CommandBase { */ @NotNull default List tabComplete(@NotNull CommandSender sender, - @NotNull List args) { + @NotNull List args) { return new ArrayList<>(); } @@ -110,67 +114,68 @@ public interface CommandBase { */ @NotNull default List tabComplete(@NotNull Player sender, - @NotNull List args) { + @NotNull List args) { return new ArrayList<>(); } - void register(); - - void unregister(); /** - * Throws an exception and sends a lang message if obj null + * Throws an exception and sends a lang message if obj null. * - * @param obj the object - * @param langTarget value in the langYml - * @param the generic type of object + * @param obj the object + * @param key key of notification message in langYml + * @param the generic type of object * @return Returns the object given or throws an exception - * @throws ArgumentAssertionException exception thrown when null + * @throws NotificationException exception thrown when null */ - default @NotNull Optional assertNonNull(@Nullable T obj, @NotNull String langTarget) - throws ArgumentAssertionException { - return Optional.empty(); + default @Nullable T notifyNull(@Nullable T obj, @NotNull String key) + throws NotificationException { + if (Objects.isNull(obj)) { + throw new NotificationException(key); + } + + return obj; } /** * Throws an exception if predicate tests false * - * @param obj Object to test with predicate - * @param predicate predicate to test - * @param langTarget value in the langYml - * @param the generic type of object + * @param obj Object to test with predicate + * @param predicate predicate to test + * @param key key of notification message in langYml + * @param the generic type of object * @return Returns the object given or throws an exception - * @throws ArgumentAssertionException + * @throws NotificationException */ - default @NotNull Optional assertPredicate(@Nullable T obj, - @NotNull Predicate predicate, @NotNull String langTarget) - throws ArgumentAssertionException { - return Optional.empty(); + default @NotNull T notifyFalse(@Nullable T obj, + @NotNull Predicate predicate, @NotNull String key) + throws NotificationException { + return obj; } /** * Throws an exception and sends a lang message if Bukkit.getPlayer(player) is null * - * @param player the player name - * @param langTarget value in the langYml + * @param player the player name + * @param key value in the langYml * @return Returns the player - * @throws ArgumentAssertionException exception thrown when invalid player + * @throws NotificationException exception thrown when invalid player */ - default @NotNull Optional assertPlayer(@NotNull String player, - @NotNull String langTarget) - throws ArgumentAssertionException { + default @NotNull Optional notifyPlayerRequired(@NotNull String player, + @NotNull String key) + throws NotificationException { return Optional.empty(); } /** - * @param condition the condition, throws exception if false - * @param langTarget value in the langYml + * @param condition the condition, throws exception if false + * @param key value in the langYml * @return Returns the condition given or throws an exception - * @throws ArgumentAssertionException exception thrown when false + * @throws NotificationException exception thrown when false */ - default boolean assertCondition(boolean condition, @NotNull String langTarget) - throws ArgumentAssertionException { + default boolean notifyFalse(boolean condition, @NotNull String key) + throws NotificationException { return true; } diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/NotificationException.java b/eco-api/src/main/java/com/willfp/eco/core/command/NotificationException.java new file mode 100644 index 00000000..b8b6f081 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/command/NotificationException.java @@ -0,0 +1,15 @@ +package com.willfp.eco.core.command; + +public class NotificationException extends Exception { + + private final String key; + + public NotificationException(String key) { + super(key); + this.key = key; + } + + public String getKey() { + return key; + } +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/RegistrableCommandBase.java b/eco-api/src/main/java/com/willfp/eco/core/command/RegistrableCommandBase.java new file mode 100644 index 00000000..b9d803fa --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/command/RegistrableCommandBase.java @@ -0,0 +1,7 @@ +package com.willfp.eco.core.command; + +public interface RegistrableCommandBase extends CommandBase { + void register(); + + void unregister(); +} diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/impl/PluginCommand.java b/eco-api/src/main/java/com/willfp/eco/core/command/impl/PluginCommand.java index 65bdc98d..3dd82826 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/command/impl/PluginCommand.java +++ b/eco-api/src/main/java/com/willfp/eco/core/command/impl/PluginCommand.java @@ -3,10 +3,10 @@ package com.willfp.eco.core.command.impl; import com.willfp.eco.core.Eco; import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.command.CommandBase; +import com.willfp.eco.core.command.RegistrableCommandBase; import org.jetbrains.annotations.NotNull; /** - * TODO REWRITE DOC ONCE COMMAND EXECUTOR REMOVED * PluginCommands are the class to be used instead of CommandExecutor, they function as the base * command, e.g. {@code /ecoenchants} would be a base command, with each subsequent argument * functioning as subcommands. @@ -15,12 +15,9 @@ import org.jetbrains.annotations.NotNull; *

* The name cannot be the same as an existing command as this will conflict. */ -/* -TODO: Do CommandExecutor Logic internally, delegate to a different class - */ -public abstract class PluginCommand implements CommandBase { +public abstract class PluginCommand implements RegistrableCommandBase { - private final CommandBase delegate; + private final RegistrableCommandBase delegate; /** @@ -32,9 +29,9 @@ public abstract class PluginCommand implements CommandBase { * @param playersOnly If only players should be able to execute this command. */ protected PluginCommand(@NotNull final EcoPlugin plugin, - @NotNull final String name, - @NotNull final String permission, - final boolean playersOnly) { + @NotNull final String name, + @NotNull final String permission, + final boolean playersOnly) { this.delegate = Eco.get().createPluginCommand(plugin, name, permission, playersOnly); } diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/impl/Subcommand.java b/eco-api/src/main/java/com/willfp/eco/core/command/impl/Subcommand.java index fe38e5a2..68b21797 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/command/impl/Subcommand.java +++ b/eco-api/src/main/java/com/willfp/eco/core/command/impl/Subcommand.java @@ -2,12 +2,13 @@ package com.willfp.eco.core.command.impl; import com.willfp.eco.core.Eco; import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.command.ArgumentAssertionException; import com.willfp.eco.core.command.CommandBase; -import java.util.Optional; +import com.willfp.eco.core.command.NotificationException; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import java.util.Optional; + /** * Subcommands can be added to PluginCommands or to other Subcommands. */ @@ -24,9 +25,9 @@ public abstract class Subcommand implements CommandBase { * @param playersOnly If the subcommand only works on players. */ protected Subcommand(@NotNull final EcoPlugin plugin, - @NotNull final String name, - @NotNull final String permission, - final boolean playersOnly) { + @NotNull final String name, + @NotNull final String permission, + final boolean playersOnly) { this.delegate = Eco.get().createSubCommand(plugin, name, permission, playersOnly); } @@ -38,8 +39,8 @@ public abstract class Subcommand implements CommandBase { * @param parent The parent command. */ protected Subcommand(@NotNull final EcoPlugin plugin, - @NotNull final String name, - @NotNull final CommandBase parent) { + @NotNull final String name, + @NotNull final CommandBase parent) { this(plugin, name, parent.getPermission(), parent.isPlayersOnly()); } @@ -64,26 +65,16 @@ public abstract class Subcommand implements CommandBase { } @Override - public final void register() { - + public @NotNull Optional notifyPlayerRequired(@NotNull String player, + @NotNull String langTarget) + throws NotificationException { + return delegate.notifyPlayerRequired(player, langTarget); } @Override - public final void unregister() { - - } - - @Override - public @NotNull Optional assertPlayer(@NotNull String player, - @NotNull String langTarget) - throws ArgumentAssertionException { - return delegate.assertPlayer(player, langTarget); - } - - @Override - public boolean assertCondition(boolean condition, @NotNull String langTarget) - throws ArgumentAssertionException { - return delegate.assertCondition(condition, langTarget); + public boolean notifyFalse(boolean condition, @NotNull String langTarget) + throws NotificationException { + return delegate.notifyFalse(condition, langTarget); } @Override diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/command/EcoPluginCommand.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/command/EcoPluginCommand.kt index 26445788..7b5890d2 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/command/EcoPluginCommand.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/command/EcoPluginCommand.kt @@ -2,24 +2,31 @@ package com.willfp.eco.internal.command import com.willfp.eco.core.Eco import com.willfp.eco.core.EcoPlugin -import com.willfp.eco.core.command.ArgumentAssertionException import com.willfp.eco.core.command.CommandBase +import com.willfp.eco.core.command.NotificationException +import com.willfp.eco.core.command.RegistrableCommandBase import org.bukkit.Bukkit -import org.bukkit.command.* +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandMap +import org.bukkit.command.CommandSender +import org.bukkit.command.TabCompleter import org.bukkit.entity.Player +import org.bukkit.util.StringUtil class EcoPluginCommand( _plugin: EcoPlugin, _name: String, _permission: String, _playersOnly: Boolean -) : CommandBase, CommandExecutor, TabCompleter { +) : RegistrableCommandBase, CommandExecutor, TabCompleter { val ecoPlugin: EcoPlugin val commandName: String val commandPermission: String val playersOnly: Boolean + val subCommands = mutableListOf() init { ecoPlugin = _plugin @@ -28,8 +35,6 @@ class EcoPluginCommand( playersOnly = _playersOnly } - val subcommands = mutableListOf() - override fun register() { val command = Bukkit.getPluginCommand(name) command?.let { c -> @@ -102,6 +107,8 @@ class EcoPluginCommand( TODO("Not yet implemented") } + override fun getSubcommands() = subCommands + fun CommandBase.handleExecution(sender: CommandSender, args: List) { if (!canExecute(sender, this, plugin)) { return @@ -124,7 +131,7 @@ class EcoPluginCommand( } try { - assertCondition(isPlayersOnly && sender !is Player, "not-player") + notifyFalse(isPlayersOnly && sender !is Player, "not-player") if (sender is Player) { onExecute(sender, args) @@ -132,14 +139,82 @@ class EcoPluginCommand( onExecute(sender, args) } - } catch (e: ArgumentAssertionException) { - sender.sendMessage(plugin.langYml.getMessage(e.langTarget)) + } catch (e: NotificationException) { + sender.sendMessage(plugin.langYml.getMessage(e.key)) return } } + /* + protected final List handleTabCompletion(@NotNull final CommandSender sender, + @NotNull final String[] args) { + + if (!sender.hasPermission(this.getPermission())) { + return null; + } + + if (args.length == 1) { + List completions = new ArrayList<>(); + + StringUtil.copyPartialMatches( + args[0], + this.getSubcommands().stream() + .filter(subCommand -> sender.hasPermission(subCommand.getPermission())) + .map(CommandBase::getName) + .collect(Collectors.toList()), + completions + ); + + Collections.sort(completions); + + if (!completions.isEmpty()) { + return completions; + } + } + + if (args.length >= 2) { + HandledCommand command = null; + + for (CommandBase subcommand : this.getSubcommands()) { + if (!sender.hasPermission(subcommand.getPermission())) { + continue; + } + + if (args[0].equalsIgnoreCase(subcommand.getName())) { + command = (HandledCommand) subcommand; + } + } + + if (command != null) { + return command.handleTabCompletion(sender, Arrays.copyOfRange(args, 1, args.length)); + } + } + + if (this.getTabCompleter() != null) { + return this.getTabCompleter().tabComplete(sender, Arrays.asList(args)); + } else { + List completions = new ArrayList<>(this.tabComplete(sender, Arrays.asList(args))); + if (sender instanceof Player player) { + completions.addAll(this.tabComplete(player, Arrays.asList(args))); + } + return completions; + } + } + */ fun CommandBase.handleTabComplete(sender: CommandSender, args: List): List { - TODO("Havent done this yet") + if (!sender.hasPermission(permission) || args.isEmpty()) return emptyList() + + val completions = subCommands.filter { sender.hasPermission(it.permission) }.map { it.name }.sorted() + + return when (args.size) { + 1 -> { + val list = mutableListOf() + StringUtil.copyPartialMatches(args[0], completions, list) + list + } + + else -> completions + } } companion object {