| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- package me.lethunderhawk.fluxapi.util.command;
- import io.papermc.paper.command.brigadier.BasicCommand;
- import io.papermc.paper.command.brigadier.CommandSourceStack;
- import me.lethunderhawk.fluxapi.util.interfaces.FluxAPIModule;
- import net.kyori.adventure.text.Component;
- import net.kyori.adventure.text.format.NamedTextColor;
- import org.bukkit.command.CommandSender;
- import org.jetbrains.annotations.ApiStatus;
- import org.jspecify.annotations.NonNull;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.List;
- import java.util.function.BiConsumer;
- import java.util.stream.Collectors;
- public abstract class CustomCommand implements BasicCommand {
- protected CommandNode rootCommand;
- protected final FluxAPIModule module;
- public CustomCommand(FluxAPIModule module) {
- this.module = module;
- this.rootCommand = getRootCommand();
- createHelpCommand();
- createCommands();
- }
- public void execute(CommandSourceStack commandSourceStack, String[] args) {
- CommandSender sender = commandSourceStack.getSender();
- if (args.length == 0) {
- if(rootCommand.getExecutor() != null) {
- rootCommand.getExecutor().accept(sender, args);
- }else{
- sendHelp(sender);
- }
- return;
- }
- List<String> argList = new ArrayList<>(Arrays.asList(args));
- CommandNode currentNode = rootCommand;
- CommandNode targetNode = null;
- // Traverse the command tree
- while (!argList.isEmpty()) {
- String nextArg = argList.get(0);
- CommandNode nextNode = currentNode.getSubCommand(nextArg);
- if (nextNode == null) {
- // No matching subcommand found, use current node if it has an executor
- targetNode = currentNode.getExecutor() != null ? currentNode : null;
- break;
- }
- currentNode = nextNode;
- argList.remove(0);
- // If this is the last argument or node has no further subcommands
- if (argList.isEmpty() || nextNode.getSubCommands().isEmpty()) {
- targetNode = nextNode;
- break;
- }
- }
- if (targetNode == null) {
- module.sendText(sender, Component.text("Unknown command. Use /" + rootCommand.getName() +" help for available commands.", NamedTextColor.RED));
- return;
- }
- if (targetNode.getExecutor() == null) {
- module.sendText(sender,Component.text("This command requires additional arguments.", NamedTextColor.RED));
- sendSubCommands(sender, targetNode);
- return;
- }
- // Execute the command with remaining arguments
- String[] remainingArgs = argList.toArray(new String[0]);
- targetNode.getExecutor().accept(sender, remainingArgs);
- }
- @ApiStatus.OverrideOnly
- public @NonNull Collection<String> suggest(final CommandSourceStack commandSourceStack, final String[] args) {
- List<String> suggestions = new ArrayList<>();
- if (args.length == 0) {
- CommandNode currentNode = rootCommand;
- if (currentNode.getTabCompleter() != null) {
- suggestions.addAll(currentNode.getTabCompleter().apply(commandSourceStack.getSender(), args));
- } else {
- // Suggest subcommands
- suggestions.addAll(currentNode.getSubCommandNames());
- }
- return suggestions;
- }
- // Start at root and traverse
- CommandNode currentNode = rootCommand;
- List<String> argList = new ArrayList<>(Arrays.asList(args));
- String lastArg = args[args.length - 1].toLowerCase();
- // Try to traverse as far as possible
- for (int i = 0; i < argList.size() - 1; i++) {
- String arg = argList.get(i);
- CommandNode nextNode = currentNode.getSubCommand(arg);
- if (nextNode == null) {
- break;
- }
- currentNode = nextNode;
- }
- // Get suggestions from current node
- if (currentNode.getTabCompleter() != null) {
- suggestions.addAll(currentNode.getTabCompleter().apply(commandSourceStack.getSender(), args));
- } else {
- // Suggest subcommands
- suggestions.addAll(currentNode.getSubCommandNames().stream()
- .filter(name -> name.toLowerCase().startsWith(lastArg))
- .collect(Collectors.toList()));
- }
- return suggestions;
- }
- @ApiStatus.OverrideOnly
- public abstract CommandNode getRootCommand();
- private void createHelpCommand() {
- rootCommand.addSubCommand(new CommandNode("help", "Displays this help menu", this::sendHelp));
- }
- @ApiStatus.OverrideOnly
- public abstract void createCommands();
- protected void sendHelp(CommandSender sender, String[] strings) {
- sendHelp(sender);
- }
- protected void sendHelp(CommandSender sender) {
- sender.sendMessage("§6=== Available Commands ===");
- for (CommandNode cmd : rootCommand.getSubCommands()) {
- sender.sendMessage("/" + rootCommand.getName() + " " + cmd.getName() + " §7- " + cmd.getDescription());
- }
- }
- private void sendSubCommands(CommandSender sender, CommandNode node) {
- sender.sendMessage("§6Available subcommands:");
- for (CommandNode subCmd : node.getSubCommands()) {
- sender.sendMessage("§e" + subCmd.getName() + " §7- " + subCmd.getDescription());
- }
- }
- public CommandNode registerSubCommand(String name, String description, BiConsumer<CommandSender, String[]> executor) {
- return rootCommand.registerSubCommand(name, description, executor);
- }
- public void reload(){
- createCommands();
- }
- }
|