progress commit

This commit is contained in:
Samuel Pizette
2022-12-04 17:52:05 -05:00
parent f7ea5fd182
commit 00f18519b0
8 changed files with 178 additions and 102 deletions

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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<CommandBase> getSubcommands();
/**
* Handle command execution.
@@ -73,7 +77,7 @@ public interface CommandBase {
* @param args The args.
*/
default void onExecute(@NotNull CommandSender sender,
@NotNull List<String> args) throws ArgumentAssertionException {
@NotNull List<String> args) throws NotificationException {
// Do nothing.
}
@@ -84,7 +88,7 @@ public interface CommandBase {
* @param args The args.
*/
default void onExecute(@NotNull Player sender,
@NotNull List<String> args) throws ArgumentAssertionException {
@NotNull List<String> args) throws NotificationException {
// Do nothing.
}
@@ -97,7 +101,7 @@ public interface CommandBase {
*/
@NotNull
default List<String> tabComplete(@NotNull CommandSender sender,
@NotNull List<String> args) {
@NotNull List<String> args) {
return new ArrayList<>();
}
@@ -110,67 +114,68 @@ public interface CommandBase {
*/
@NotNull
default List<String> tabComplete(@NotNull Player sender,
@NotNull List<String> args) {
@NotNull List<String> 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 <T> the generic type of object
* @param obj the object
* @param key key of notification message in langYml
* @param <T> 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 <T> Optional<T> assertNonNull(@Nullable T obj, @NotNull String langTarget)
throws ArgumentAssertionException {
return Optional.empty();
default @Nullable <T> 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 <T> 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 <T> the generic type of object
* @return Returns the object given or throws an exception
* @throws ArgumentAssertionException
* @throws NotificationException
*/
default @NotNull <T> Optional<T> assertPredicate(@Nullable T obj,
@NotNull Predicate<T> predicate, @NotNull String langTarget)
throws ArgumentAssertionException {
return Optional.empty();
default @NotNull <T> T notifyFalse(@Nullable T obj,
@NotNull Predicate<T> 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<Player> assertPlayer(@NotNull String player,
@NotNull String langTarget)
throws ArgumentAssertionException {
default @NotNull Optional<Player> 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;
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,7 @@
package com.willfp.eco.core.command;
public interface RegistrableCommandBase extends CommandBase {
void register();
void unregister();
}

View File

@@ -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;
* <p>
* 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);
}

View File

@@ -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<Player> notifyPlayerRequired(@NotNull String player,
@NotNull String langTarget)
throws NotificationException {
return delegate.notifyPlayerRequired(player, langTarget);
}
@Override
public final void unregister() {
}
@Override
public @NotNull Optional<Player> 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

View File

@@ -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<CommandBase>()
init {
ecoPlugin = _plugin
@@ -28,8 +35,6 @@ class EcoPluginCommand(
playersOnly = _playersOnly
}
val subcommands = mutableListOf<CommandBase>()
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<String>) {
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<String> handleTabCompletion(@NotNull final CommandSender sender,
@NotNull final String[] args) {
if (!sender.hasPermission(this.getPermission())) {
return null;
}
if (args.length == 1) {
List<String> 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<String> 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<String>): List<String> {
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<String>()
StringUtil.copyPartialMatches(args[0], completions, list)
list
}
else -> completions
}
}
companion object {