diff --git a/src/main/java/com/songoda/ultimatestacker/command/AbstractCommand.java b/src/main/java/com/songoda/ultimatestacker/command/AbstractCommand.java index ebdcd47..331db15 100644 --- a/src/main/java/com/songoda/ultimatestacker/command/AbstractCommand.java +++ b/src/main/java/com/songoda/ultimatestacker/command/AbstractCommand.java @@ -3,18 +3,36 @@ package com.songoda.ultimatestacker.command; import com.songoda.ultimatestacker.UltimateStacker; import org.bukkit.command.CommandSender; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public abstract class AbstractCommand { - private final AbstractCommand parent; - private final String command; private final boolean noConsole; + private AbstractCommand parent = null; + private boolean hasArgs = false; + private String command; - protected AbstractCommand(String command, AbstractCommand parent, boolean noConsole) { - this.command = command; + private List subCommand = new ArrayList<>(); + + protected AbstractCommand(AbstractCommand parent, boolean noConsole, String... command) { + if (parent != null) { + this.subCommand = Arrays.asList(command); + } else { + this.command = Arrays.asList(command).get(0); + } this.parent = parent; this.noConsole = noConsole; } + protected AbstractCommand(boolean noConsole, boolean hasArgs, String... command) { + this.command = Arrays.asList(command).get(0); + + this.hasArgs = hasArgs; + this.noConsole = noConsole; + } + public AbstractCommand getParent() { return parent; } @@ -23,17 +41,32 @@ public abstract class AbstractCommand { return command; } - public boolean isNoConsole() { - return noConsole; + public List getSubCommand() { + return subCommand; + } + + public void addSubCommand(String command) { + subCommand.add(command); } protected abstract ReturnType runCommand(UltimateStacker instance, CommandSender sender, String... args); + protected abstract List onTab(UltimateStacker instance, CommandSender sender, String... args); + public abstract String getPermissionNode(); public abstract String getSyntax(); public abstract String getDescription(); + public boolean hasArgs() { + return hasArgs; + } + + public boolean isNoConsole() { + return noConsole; + } + public enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR} } + diff --git a/src/main/java/com/songoda/ultimatestacker/command/CommandManager.java b/src/main/java/com/songoda/ultimatestacker/command/CommandManager.java index 5b0dae1..6aeac2d 100644 --- a/src/main/java/com/songoda/ultimatestacker/command/CommandManager.java +++ b/src/main/java/com/songoda/ultimatestacker/command/CommandManager.java @@ -2,7 +2,6 @@ package com.songoda.ultimatestacker.command; import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.command.commands.*; -import com.songoda.ultimatestacker.utils.Methods; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -15,20 +14,27 @@ import java.util.List; public class CommandManager implements CommandExecutor { private static final List commands = new ArrayList<>(); - private UltimateStacker instance; + private UltimateStacker plugin; + private TabManager tabManager; - public CommandManager(UltimateStacker instance) { - this.instance = instance; + public CommandManager(UltimateStacker plugin) { + this.plugin = plugin; + this.tabManager = new TabManager(this); - instance.getCommand("UltimateStacker").setExecutor(this); + plugin.getCommand("UltimateStacker").setExecutor(this); AbstractCommand commandUltimateStacker = addCommand(new CommandUltimateStacker()); addCommand(new CommandSettings(commandUltimateStacker)); addCommand(new CommandRemoveAll(commandUltimateStacker)); addCommand(new CommandReload(commandUltimateStacker)); - addCommand(new CommandGive(commandUltimateStacker)); + addCommand(new CommandGiveSpawner(commandUltimateStacker)); addCommand(new CommandConvert(commandUltimateStacker)); + + for (AbstractCommand abstractCommand : commands) { + if (abstractCommand.getParent() != null) continue; + plugin.getCommand(abstractCommand.getCommand()).setTabCompleter(tabManager); + } } private AbstractCommand addCommand(AbstractCommand abstractCommand) { @@ -39,20 +45,23 @@ public class CommandManager implements CommandExecutor { @Override public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) { for (AbstractCommand abstractCommand : commands) { - if (abstractCommand.getCommand().equalsIgnoreCase(command.getName())) { - if (strings.length == 0) { + if (abstractCommand.getCommand() != null && abstractCommand.getCommand().equalsIgnoreCase(command.getName().toLowerCase())) { + if (strings.length == 0 || abstractCommand.hasArgs()) { processRequirements(abstractCommand, commandSender, strings); return true; } } else if (strings.length != 0 && abstractCommand.getParent() != null && abstractCommand.getParent().getCommand().equalsIgnoreCase(command.getName())) { String cmd = strings[0]; - if (cmd.equalsIgnoreCase(abstractCommand.getCommand())) { - processRequirements(abstractCommand, commandSender, strings); - return true; + String cmd2 = strings.length >= 2 ? String.join(" ", strings[0], strings[1]) : null; + for (String cmds : abstractCommand.getSubCommand()) { + if (cmd.equalsIgnoreCase(cmds) || (cmd2 != null && cmd2.equalsIgnoreCase(cmds))) { + processRequirements(abstractCommand, commandSender, strings); + return true; + } } } } - instance.getLocale().newMessage("&7The command you entered does not exist or is spelt incorrectly.").sendPrefixedMessage(commandSender); + plugin.getLocale().newMessage("&7The command you entered does not exist or is spelt incorrectly.").sendPrefixedMessage(commandSender); return true; } @@ -62,14 +71,14 @@ public class CommandManager implements CommandExecutor { return; } if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) { - AbstractCommand.ReturnType returnType = command.runCommand(instance, sender, strings); + AbstractCommand.ReturnType returnType = command.runCommand(plugin, sender, strings); if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) { - instance.getLocale().newMessage("&cInvalid Syntax!").sendPrefixedMessage(sender); - instance.getLocale().newMessage("&7The valid syntax is: &6" + command.getSyntax() + "&7.").sendPrefixedMessage(sender); + plugin.getLocale().newMessage("&cInvalid Syntax!").sendPrefixedMessage(sender); + plugin.getLocale().newMessage("&7The valid syntax is: &6" + command.getSyntax() + "&7.").sendPrefixedMessage(sender); } return; } - instance.getLocale().getMessage("event.general.nopermission").sendPrefixedMessage(sender); + plugin.getLocale().getMessage("event.general.nopermission").sendPrefixedMessage(sender); } public List getCommands() { diff --git a/src/main/java/com/songoda/ultimatestacker/command/TabManager.java b/src/main/java/com/songoda/ultimatestacker/command/TabManager.java new file mode 100644 index 0000000..e28c93d --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/command/TabManager.java @@ -0,0 +1,64 @@ +package com.songoda.ultimatestacker.command; + +import com.songoda.ultimatestacker.UltimateStacker; +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; + +import java.util.ArrayList; +import java.util.List; + +public class TabManager implements TabCompleter { + + private final CommandManager commandManager; + + TabManager(CommandManager commandManager) { + this.commandManager = commandManager; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] strings) { + for (AbstractCommand abstractCommand : commandManager.getCommands()) { + if (abstractCommand.getCommand() != null && abstractCommand.getCommand().equalsIgnoreCase(command.getName()) && !abstractCommand.hasArgs()) { + if (strings.length == 1) { + List subs = new ArrayList<>(); + for (AbstractCommand ac : commandManager.getCommands()) { + if (ac.getSubCommand() == null) continue; + subs.addAll(ac.getSubCommand()); + } + subs.removeIf(s -> !s.toLowerCase().startsWith(strings[0].toLowerCase())); + return subs; + } + } else if (strings.length != 0 && abstractCommand.getParent() != null && abstractCommand.getParent().getCommand().equalsIgnoreCase(command.getName()) + || abstractCommand.hasArgs() && abstractCommand.getCommand().equalsIgnoreCase(command.getName())) { + String[] args = abstractCommand.hasArgs() ? (String[]) ArrayUtils.add(strings, 0, command.getName()) : strings; + String cmd = abstractCommand.hasArgs() ? command.getName() : args[0]; + String cmd2 = args.length >= 2 ? String.join(" ", args[0], args[1]) : null; + if (!abstractCommand.hasArgs()) { + for (String cmds : abstractCommand.getSubCommand()) { + if (cmd.equalsIgnoreCase(cmds) || (cmd2 != null && cmd2.equalsIgnoreCase(cmds))) { + return fetchList(abstractCommand, args, sender); + } + } + } else { + return fetchList(abstractCommand, args, sender); + } + } + } + return new ArrayList<>(); + } + + private List fetchList(AbstractCommand abstractCommand, String[] args, CommandSender sender) { + List list = abstractCommand.onTab(UltimateStacker.getInstance(), sender, args); + String str = args[args.length - 1]; + if (list != null && str != null && str.length() >= 1) { + try { + list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase())); + } catch (UnsupportedOperationException ignored) { + } + } + return list; + } + +} diff --git a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandConvert.java b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandConvert.java index dce7382..c2cdd1c 100644 --- a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandConvert.java +++ b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandConvert.java @@ -8,10 +8,12 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.List; + public class CommandConvert extends AbstractCommand { public CommandConvert(AbstractCommand parent) { - super("convert", parent, true); + super(parent, true, "convert"); } @Override @@ -26,6 +28,11 @@ public class CommandConvert extends AbstractCommand { return ReturnType.SUCCESS; } + @Override + protected List onTab(UltimateStacker instance, CommandSender sender, String... args) { + return null; + } + @Override public String getPermissionNode() { return "ultimatestacker.admin"; diff --git a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandReload.java b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandReload.java index 3cd42da..eb5bad3 100644 --- a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandReload.java +++ b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandReload.java @@ -2,13 +2,14 @@ package com.songoda.ultimatestacker.command.commands; import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.command.AbstractCommand; -import com.songoda.ultimatestacker.utils.Methods; import org.bukkit.command.CommandSender; +import java.util.List; + public class CommandReload extends AbstractCommand { public CommandReload(AbstractCommand parent) { - super("reload", parent, false); + super(parent, false, "reload"); } @Override @@ -18,6 +19,11 @@ public class CommandReload extends AbstractCommand { return ReturnType.SUCCESS; } + @Override + protected List onTab(UltimateStacker instance, CommandSender sender, String... args) { + return null; + } + @Override public String getPermissionNode() { return "ultimatestacker.admin"; diff --git a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandRemoveAll.java b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandRemoveAll.java index 178315c..bed9534 100644 --- a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandRemoveAll.java +++ b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandRemoveAll.java @@ -13,10 +13,12 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import java.util.List; + public class CommandRemoveAll extends AbstractCommand { public CommandRemoveAll(AbstractCommand parent) { - super("removeall", parent, false); + super(parent, false, "removeall"); } @Override @@ -62,6 +64,11 @@ public class CommandRemoveAll extends AbstractCommand { return ReturnType.SUCCESS; } + @Override + protected List onTab(UltimateStacker instance, CommandSender sender, String... args) { + return null; + } + @Override public String getPermissionNode() { return "ultimatestacker.admin"; diff --git a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandSettings.java b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandSettings.java index b387067..205c8cf 100644 --- a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandSettings.java +++ b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandSettings.java @@ -5,10 +5,12 @@ import com.songoda.ultimatestacker.command.AbstractCommand; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.List; + public class CommandSettings extends AbstractCommand { public CommandSettings(AbstractCommand parent) { - super("Settings", parent, true); + super(parent, true, "Settings"); } @Override @@ -17,6 +19,11 @@ public class CommandSettings extends AbstractCommand { return ReturnType.SUCCESS; } + @Override + protected List onTab(UltimateStacker instance, CommandSender sender, String... args) { + return null; + } + @Override public String getPermissionNode() { return "ultimatestacker.admin"; diff --git a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandUltimateStacker.java b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandUltimateStacker.java index 2f07d3d..394510a 100644 --- a/src/main/java/com/songoda/ultimatestacker/command/commands/CommandUltimateStacker.java +++ b/src/main/java/com/songoda/ultimatestacker/command/commands/CommandUltimateStacker.java @@ -5,10 +5,12 @@ import com.songoda.ultimatestacker.command.AbstractCommand; import com.songoda.ultimatestacker.utils.Methods; import org.bukkit.command.CommandSender; +import java.util.List; + public class CommandUltimateStacker extends AbstractCommand { public CommandUltimateStacker() { - super("UltimateStacker", null, false); + super(null, false, "UltimateStacker"); } @Override @@ -27,6 +29,11 @@ public class CommandUltimateStacker extends AbstractCommand { return ReturnType.SUCCESS; } + @Override + protected List onTab(UltimateStacker instance, CommandSender sender, String... args) { + return null; + } + @Override public String getPermissionNode() { return null; diff --git a/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class b/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class index 352bc52..5ceb7ca 100644 Binary files a/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class and b/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class differ