MinionCommand.java 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package me.lethunderhawk.minion.command;
  2. import me.lethunderhawk.bazaarflux.util.command.CommandNode;
  3. import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
  4. import me.lethunderhawk.clans.ClanModule;
  5. import me.lethunderhawk.minion.MinionModule;
  6. import me.lethunderhawk.minion.manager.MinionManager;
  7. import me.lethunderhawk.minion.ui.minionList.MinionLevelListMenu;
  8. import me.lethunderhawk.minion.ui.minionList.MinionListMenu;
  9. import org.bukkit.command.Command;
  10. import org.bukkit.command.CommandExecutor;
  11. import org.bukkit.command.CommandSender;
  12. import org.bukkit.command.TabCompleter;
  13. import org.bukkit.entity.Player;
  14. import org.bukkit.inventory.ItemStack;
  15. import java.util.ArrayList;
  16. import java.util.Arrays;
  17. import java.util.List;
  18. import java.util.function.BiConsumer;
  19. import java.util.stream.Collectors;
  20. public class MinionCommand implements CommandExecutor, TabCompleter {
  21. private final CommandNode rootCommand;
  22. private final MinionModule module;
  23. public MinionCommand(MinionModule minionModule) {
  24. this.module = minionModule;
  25. this.rootCommand = new CommandNode("clan", "Main clan command", null);
  26. setupDefaultCommands();
  27. }
  28. private void setupDefaultCommands() {
  29. registerCommand("all", "get all minions", this::getAll);
  30. registerCommand("reload", "reload", this::reload);
  31. registerCommand("removeAll", "remove all minions", this::removeAll);
  32. CommandNode menu = registerCommand("menu", "See all minion types in a GUI", this::showMenu);
  33. CommandNode cobble = new CommandNode("cobblestone", "See all cobblestone minions", this::showCobbleMenu);
  34. menu.addSubCommands(cobble);
  35. }
  36. private void showCobbleMenu(CommandSender sender, String[] strings) {
  37. if(sender instanceof Player p) {
  38. InventoryManager.openFor(p, new MinionLevelListMenu("cobblestone"));
  39. }
  40. }
  41. private void showMenu(CommandSender sender, String[] strings) {
  42. if(strings.length == 0 && sender instanceof Player p) {
  43. InventoryManager.openFor(p, new MinionListMenu());
  44. }
  45. }
  46. private void removeAll(CommandSender sender, String[] strings) {
  47. MinionManager.stopAndUnregisterAll();
  48. }
  49. private void reload(CommandSender sender, String[] strings) {
  50. module.reload();
  51. }
  52. private void getAll(CommandSender sender, String[] strings) {
  53. if(!(sender instanceof Player p)) return;
  54. for(ItemStack minion : module.getAllMinions()){
  55. p.getInventory().addItem(minion);
  56. }
  57. }
  58. // Helper method to easily register commands
  59. public CommandNode registerCommand(String name, String description, BiConsumer<CommandSender, String[]> executor) {
  60. return rootCommand.registerSubCommand(name, description, executor);
  61. }
  62. @Override
  63. public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
  64. if (args.length == 0) {
  65. sendHelp(sender);
  66. return true;
  67. }
  68. List<String> argList = new ArrayList<>(Arrays.asList(args));
  69. CommandNode currentNode = rootCommand;
  70. CommandNode targetNode = null;
  71. // Traverse the command tree
  72. while (!argList.isEmpty()) {
  73. String nextArg = argList.get(0);
  74. CommandNode nextNode = currentNode.getSubCommand(nextArg);
  75. if (nextNode == null) {
  76. // No matching subcommand found, use current node if it has an executor
  77. targetNode = currentNode.getExecutor() != null ? currentNode : null;
  78. break;
  79. }
  80. currentNode = nextNode;
  81. argList.remove(0);
  82. // If this is the last argument or node has no further subcommands
  83. if (argList.isEmpty() || nextNode.getSubCommands().isEmpty()) {
  84. targetNode = nextNode;
  85. break;
  86. }
  87. }
  88. if (targetNode == null) {
  89. ClanModule.sendText(sender,"§cUnknown command. Use /minion help for available commands.");
  90. return true;
  91. }
  92. if (targetNode.getExecutor() == null) {
  93. ClanModule.sendText(sender,"§cThis command requires additional arguments.");
  94. sendSubCommands(sender, targetNode);
  95. return true;
  96. }
  97. // Execute the command with remaining arguments
  98. String[] remainingArgs = argList.toArray(new String[0]);
  99. targetNode.getExecutor().accept(sender, remainingArgs);
  100. return true;
  101. }
  102. @Override
  103. public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
  104. List<String> suggestions = new ArrayList<>();
  105. if (args.length == 0) {
  106. return suggestions;
  107. }
  108. // Start at root and traverse
  109. CommandNode currentNode = rootCommand;
  110. List<String> argList = new ArrayList<>(Arrays.asList(args));
  111. String lastArg = args[args.length - 1].toLowerCase();
  112. // Try to traverse as far as possible
  113. for (int i = 0; i < argList.size() - 1; i++) {
  114. String arg = argList.get(i);
  115. CommandNode nextNode = currentNode.getSubCommand(arg);
  116. if (nextNode == null) {
  117. break;
  118. }
  119. currentNode = nextNode;
  120. }
  121. // Get suggestions from current node
  122. if (currentNode.getTabCompleter() != null) {
  123. suggestions.addAll(currentNode.getTabCompleter().apply(sender, args));
  124. } else {
  125. // Suggest subcommands
  126. suggestions.addAll(currentNode.getSubCommandNames().stream()
  127. .filter(name -> name.toLowerCase().startsWith(lastArg))
  128. .collect(Collectors.toList()));
  129. }
  130. return suggestions;
  131. }
  132. private void sendHelp(CommandSender sender) {
  133. sender.sendMessage("§6=== Minion Commands ===");
  134. for (CommandNode cmd : rootCommand.getSubCommands()) {
  135. sender.sendMessage("§e/minion " + cmd.getName() + " §7- " + cmd.getDescription());
  136. }
  137. }
  138. private void sendSubCommands(CommandSender sender, CommandNode node) {
  139. sender.sendMessage("§6Available subcommands:");
  140. for (CommandNode subCmd : node.getSubCommands()) {
  141. sender.sendMessage("§e" + subCmd.getName() + " §7- " + subCmd.getDescription());
  142. }
  143. }
  144. }