Improved subcommand system
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.command.AbstractCommand;
|
||||
import com.willfp.eco.core.command.impl.BaseCommand;
|
||||
import com.willfp.eco.core.command.impl.PluginCommand;
|
||||
import com.willfp.eco.core.config.ConfigHandler;
|
||||
import com.willfp.eco.core.config.base.ConfigYml;
|
||||
import com.willfp.eco.core.config.base.LangYml;
|
||||
@@ -396,7 +396,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
this.getListeners().forEach(listener -> this.getEventManager().registerListener(listener));
|
||||
|
||||
this.getCommands().forEach(AbstractCommand::register);
|
||||
this.getPluginCommands().forEach(BaseCommand::register);
|
||||
this.getPluginCommands().forEach(PluginCommand::register);
|
||||
|
||||
this.getScheduler().runLater(this::afterLoad, 1);
|
||||
|
||||
@@ -567,7 +567,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
*
|
||||
* @return A list of commands.
|
||||
*/
|
||||
public List<BaseCommand> getPluginCommands() {
|
||||
public List<PluginCommand> getPluginCommands() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.core.command.CommandHandler;
|
||||
import com.willfp.eco.core.command.TabCompleteHandler;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class HandledCommand implements CommandBase, CommandExecutor, TabCompleter {
|
||||
/**
|
||||
* The name of the command.
|
||||
*/
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The permission required to execute the command.
|
||||
* <p>
|
||||
* Written out as a string for flexibility with subclasses.
|
||||
*/
|
||||
@Getter
|
||||
private final String permission;
|
||||
|
||||
/**
|
||||
* Should the command only be allowed to be executed by players?
|
||||
* <p>
|
||||
* In other worlds, only allowed to be executed by console.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean playersOnly;
|
||||
|
||||
/**
|
||||
* All subcommands for the command.
|
||||
*/
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final List<CommandBase> subcommands;
|
||||
|
||||
/**
|
||||
* Create a new command.
|
||||
* <p>
|
||||
* The name cannot be the same as an existing command as this will conflict.
|
||||
*
|
||||
* @param name The name used in execution.
|
||||
* @param permission The permission required to execute the command.
|
||||
* @param playersOnly If only players should be able to execute this command.
|
||||
*/
|
||||
protected HandledCommand(@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
this.name = name;
|
||||
this.permission = permission;
|
||||
this.playersOnly = playersOnly;
|
||||
this.subcommands = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a subcommand to the command.
|
||||
*
|
||||
* @param subcommand The subcommand.
|
||||
* @return The parent command.
|
||||
*/
|
||||
@Override
|
||||
public final CommandBase addSubcommand(@NotNull final CommandBase subcommand) {
|
||||
subcommands.add(subcommand);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract CommandHandler getHandler();
|
||||
|
||||
@Override
|
||||
public TabCompleteHandler getTabCompleter() {
|
||||
return (sender, args) -> new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,32 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.core.command.util.CommandUtils;
|
||||
import com.willfp.eco.internal.commands.HandledCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.util.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class BaseCommand extends HandledCommand implements CommandExecutor, TabCompleter {
|
||||
public abstract class PluginCommand extends HandledCommand implements CommandExecutor, TabCompleter {
|
||||
/**
|
||||
* Create a new command.
|
||||
* <p>
|
||||
* The command will not be registered until {@link this#register()} is called.
|
||||
* <p>
|
||||
* The name cannot be the same as an existing command as this will conflict.
|
||||
*
|
||||
* @param name The name used in execution.
|
||||
* @param permission The permission required to execute the command.
|
||||
* @param playersOnly If only players should be able to execute this command.
|
||||
*/
|
||||
protected BaseCommand(@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
protected PluginCommand(@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
super(name, permission, playersOnly);
|
||||
}
|
||||
|
||||
@@ -42,7 +36,7 @@ public abstract class BaseCommand extends HandledCommand implements CommandExecu
|
||||
* Requires the command name to exist, defined in plugin.yml.
|
||||
*/
|
||||
public final void register() {
|
||||
PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
||||
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
||||
assert command != null;
|
||||
command.setExecutor(this);
|
||||
command.setTabCompleter(this);
|
||||
@@ -67,25 +61,7 @@ public abstract class BaseCommand extends HandledCommand implements CommandExecu
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CommandUtils.canExecute(sender, this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length > 0) {
|
||||
for (CommandBase subcommand : this.getSubcommands()) {
|
||||
if (subcommand.getName().equalsIgnoreCase(args[0])) {
|
||||
if (!CommandUtils.canExecute(sender, subcommand)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
subcommand.getHandler().onExecute(sender, Arrays.asList(Arrays.copyOfRange(args, 1, args.length)));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
||||
this.handle(sender, args);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -109,26 +85,6 @@ public abstract class BaseCommand extends HandledCommand implements CommandExecu
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!sender.hasPermission(this.getPermission())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (args.length > 0) {
|
||||
List<String> completions = new ArrayList<>();
|
||||
|
||||
StringUtil.copyPartialMatches(
|
||||
args[0],
|
||||
this.getSubcommands().stream().map(CommandBase::getName).collect(Collectors.toList()),
|
||||
completions
|
||||
);
|
||||
|
||||
Collections.sort(completions);
|
||||
|
||||
if (!completions.isEmpty()) {
|
||||
return completions;
|
||||
}
|
||||
}
|
||||
|
||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
||||
return this.handleTabCompletion(sender, args);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.internal.commands.HandledCommand;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class Subcommand extends HandledCommand {
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
package com.willfp.eco.internal.commands;
|
||||
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.core.command.CommandHandler;
|
||||
import com.willfp.eco.core.command.TabCompleteHandler;
|
||||
import com.willfp.eco.core.command.util.CommandUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.util.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class HandledCommand implements CommandBase, CommandExecutor, TabCompleter {
|
||||
/**
|
||||
* The name of the command.
|
||||
*/
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The permission required to execute the command.
|
||||
* <p>
|
||||
* Written out as a string for flexibility with subclasses.
|
||||
*/
|
||||
@Getter
|
||||
private final String permission;
|
||||
|
||||
/**
|
||||
* Should the command only be allowed to be executed by players?
|
||||
* <p>
|
||||
* In other worlds, only allowed to be executed by console.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean playersOnly;
|
||||
|
||||
/**
|
||||
* All subcommands for the command.
|
||||
*/
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
private final List<CommandBase> subcommands;
|
||||
|
||||
/**
|
||||
* Create a new command.
|
||||
* <p>
|
||||
* The name cannot be the same as an existing command as this will conflict.
|
||||
*
|
||||
* @param name The name used in execution.
|
||||
* @param permission The permission required to execute the command.
|
||||
* @param playersOnly If only players should be able to execute this command.
|
||||
*/
|
||||
protected HandledCommand(@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
this.name = name;
|
||||
this.permission = permission;
|
||||
this.playersOnly = playersOnly;
|
||||
this.subcommands = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a subcommand to the command.
|
||||
*
|
||||
* @param subcommand The subcommand.
|
||||
* @return The parent command.
|
||||
*/
|
||||
@Override
|
||||
public final CommandBase addSubcommand(@NotNull final CommandBase subcommand) {
|
||||
subcommands.add(subcommand);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the command.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
protected final void handle(@NotNull final CommandSender sender,
|
||||
@NotNull final String[] args) {
|
||||
if (!CommandUtils.canExecute(sender, this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length > 0) {
|
||||
for (CommandBase subcommand : this.getSubcommands()) {
|
||||
if (subcommand.getName().equalsIgnoreCase(args[0])) {
|
||||
if (!CommandUtils.canExecute(sender, subcommand)) {
|
||||
return;
|
||||
}
|
||||
|
||||
((HandledCommand) subcommand).handle(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the tab completion.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
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().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 (args[0].equalsIgnoreCase(subcommand.getName())) {
|
||||
command = (HandledCommand) subcommand;
|
||||
}
|
||||
}
|
||||
|
||||
if (command != null) {
|
||||
return command.handleTabCompletion(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
}
|
||||
|
||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract CommandHandler getHandler();
|
||||
|
||||
@Override
|
||||
public TabCompleteHandler getTabCompleter() {
|
||||
return (sender, args) -> new ArrayList<>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user