diff --git a/docs/acf-core/co/aikar/commands/BaseCommand.html b/docs/acf-core/co/aikar/commands/BaseCommand.html index b9b42773..844b9eac 100644 --- a/docs/acf-core/co/aikar/commands/BaseCommand.html +++ b/docs/acf-core/co/aikar/commands/BaseCommand.html @@ -421,7 +421,7 @@ extends
  • getCurrentCommandIssuer

    -
    public CommandIssuer getCurrentCommandIssuer()
    +
    public CommandIssuer getCurrentCommandIssuer()
  • @@ -430,7 +430,7 @@ extends
  • getCurrentCommandManager

    -
    public CommandManager getCurrentCommandManager()
    +
    public CommandManager getCurrentCommandManager()
  • @@ -439,7 +439,7 @@ extends
  • canExecute

    -
    public boolean canExecute(CommandIssuer issuer,
    +
    public boolean canExecute(CommandIssuer issuer,
                               RegisteredCommand<?> cmd)
  • @@ -449,7 +449,7 @@ extends
  • tabComplete

    -
    public List<StringtabComplete(CommandIssuer issuer,
    +
    public List<StringtabComplete(CommandIssuer issuer,
                                     String commandLabel,
                                     String[] args)
                              throws IllegalArgumentException
    @@ -466,7 +466,7 @@ extends

    getCommandHelp

    @Deprecated
    -public CommandHelp getCommandHelp()
    +public CommandHelp getCommandHelp()
    Deprecated. Unstable API
  • @@ -477,7 +477,7 @@ public 

    showCommandHelp

    @Deprecated
    -public void showCommandHelp()
    +public void showCommandHelp()
    Deprecated. Unstable API
    @@ -487,7 +487,7 @@ public void 
  • help

    -
    public void help(Object issuer,
    +
    public void help(Object issuer,
                      String[] args)
  • @@ -497,7 +497,7 @@ public void 
  • help

    -
    public void help(CommandIssuer issuer,
    +
    public void help(CommandIssuer issuer,
                      String[] args)
  • @@ -507,7 +507,7 @@ public void 
  • doHelp

    -
    public void doHelp(Object issuer,
    +
    public void doHelp(Object issuer,
                        String... args)
  • @@ -517,7 +517,7 @@ public void 
  • doHelp

    -
    public void doHelp(CommandIssuer issuer,
    +
    public void doHelp(CommandIssuer issuer,
                        String... args)
  • @@ -527,7 +527,7 @@ public void 
  • showSyntax

    -
    public void showSyntax(CommandIssuer issuer,
    +
    public void showSyntax(CommandIssuer issuer,
                            RegisteredCommand<?> cmd)
  • @@ -537,7 +537,7 @@ public void 
  • hasPermission

    -
    public boolean hasPermission(Object issuer)
    +
    public boolean hasPermission(Object issuer)
  • @@ -546,7 +546,7 @@ public void 
  • hasPermission

    -
    public boolean hasPermission(CommandIssuer issuer)
    +
    public boolean hasPermission(CommandIssuer issuer)
  • @@ -555,7 +555,7 @@ public void 
  • getName

    -
    public String getName()
    +
    public String getName()
  • @@ -564,7 +564,7 @@ public void 
  • getExceptionHandler

    -
    public ExceptionHandler getExceptionHandler()
    +
    public ExceptionHandler getExceptionHandler()
  • @@ -573,7 +573,7 @@ public void 
  • setExceptionHandler

    -
    public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler)
    +
    public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler)
  • diff --git a/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html b/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html index 5c79b6f5..6eb1fef4 100644 --- a/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html +++ b/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html @@ -331,284 +331,286 @@ 323 } 324 } 325 -326 if (subCommands.get(DEFAULT) != null) { -327 executeSubcommand(commandContext, DEFAULT, issuer, args); -328 return; -329 } +326 +327 if (subCommands.get(UNKNOWN) != null) { +328 if (!executeSubcommand(commandContext, UNKNOWN, issuer, args)) { +329 help(issuer, args); 330 -331 if (!executeSubcommand(commandContext, UNKNOWN, issuer, args)) { -332 help(issuer, args); -333 } -334 } finally { -335 postCommandOperation(); -336 } -337 } -338 -339 private void postCommandOperation() { -340 CommandManager.commandOperationContext.get().pop(); -341 execSubcommand = null; -342 execLabel = null; -343 origArgs = new String[]{}; -344 } -345 -346 private CommandOperationContext preCommandOperation(CommandIssuer issuer, String commandLabel, String[] args) { -347 Stack<CommandOperationContext> contexts = CommandManager.commandOperationContext.get(); -348 CommandOperationContext context = this.manager.createCommandOperationContext(this, issuer, commandLabel, args); -349 contexts.push(context); -350 lastCommandOperationContext = context; -351 execSubcommand = null; -352 execLabel = commandLabel; -353 origArgs = args; -354 return context; -355 } -356 -357 public CommandIssuer getCurrentCommandIssuer() { -358 return CommandManager.getCurrentCommandIssuer(); -359 } -360 public CommandManager getCurrentCommandManager() { -361 return CommandManager.getCurrentCommandManager(); -362 } -363 -364 private CommandSearch findSubCommand(String[] args) { -365 return findSubCommand(args, false); -366 } -367 private CommandSearch findSubCommand(String[] args, boolean completion) { -368 for (int i = args.length; i >= 0; i--) { -369 String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase(); -370 Set<RegisteredCommand> cmds = subCommands.get(checkSub); -371 -372 final int extraArgs = args.length - i; -373 if (!cmds.isEmpty()) { -374 RegisteredCommand cmd = null; -375 if (cmds.size() == 1) { -376 cmd = Iterables.getOnlyElement(cmds); -377 } else { -378 Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> { -379 int required = c.requiredResolvers; -380 int optional = c.optionalResolvers; -381 return extraArgs <= required + optional && (completion || extraArgs >= required); -382 }).sorted((c1, c2) -> { -383 int a = c1.requiredResolvers + c1.optionalResolvers; -384 int b = c2.requiredResolvers + c2.optionalResolvers; -385 -386 if (a == b) { -387 return 0; -388 } -389 return a < b ? 1 : -1; -390 }).findFirst(); -391 if (optCmd.isPresent()) { -392 cmd = optCmd.get(); -393 } -394 } -395 if (cmd != null) { -396 return new CommandSearch(cmd, i, checkSub); -397 } -398 } -399 } -400 return null; -401 } -402 -403 private void executeCommand(CommandOperationContext commandOperationContext, -404 CommandIssuer issuer, String[] args, RegisteredCommand cmd) { -405 if (cmd.hasPermission(issuer)) { -406 commandOperationContext.setRegisteredCommand(cmd); -407 if (checkPrecommand(commandOperationContext, cmd, issuer, args)) { -408 return; -409 } -410 List<String> sargs = Lists.newArrayList(args); -411 cmd.invoke(issuer, sargs); -412 } else { -413 issuer.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED); -414 } -415 } -416 -417 public boolean canExecute(CommandIssuer issuer, RegisteredCommand<?> cmd) { -418 return true; -419 } -420 -421 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args) -422 throws IllegalArgumentException { -423 -424 commandLabel = commandLabel.toLowerCase(); -425 try { -426 CommandOperationContext commandOperationContext = preCommandOperation(issuer, commandLabel, args); -427 -428 final CommandSearch search = findSubCommand(args, true); +331 } +332 } else if (subCommands.get(DEFAULT) != null) { +333 executeSubcommand(commandContext, DEFAULT, issuer, args); +334 } +335 +336 } finally { +337 postCommandOperation(); +338 } +339 } +340 +341 private void postCommandOperation() { +342 CommandManager.commandOperationContext.get().pop(); +343 execSubcommand = null; +344 execLabel = null; +345 origArgs = new String[]{}; +346 } +347 +348 private CommandOperationContext preCommandOperation(CommandIssuer issuer, String commandLabel, String[] args) { +349 Stack<CommandOperationContext> contexts = CommandManager.commandOperationContext.get(); +350 CommandOperationContext context = this.manager.createCommandOperationContext(this, issuer, commandLabel, args); +351 contexts.push(context); +352 lastCommandOperationContext = context; +353 execSubcommand = null; +354 execLabel = commandLabel; +355 origArgs = args; +356 return context; +357 } +358 +359 public CommandIssuer getCurrentCommandIssuer() { +360 return CommandManager.getCurrentCommandIssuer(); +361 } +362 public CommandManager getCurrentCommandManager() { +363 return CommandManager.getCurrentCommandManager(); +364 } +365 +366 private CommandSearch findSubCommand(String[] args) { +367 return findSubCommand(args, false); +368 } +369 private CommandSearch findSubCommand(String[] args, boolean completion) { +370 for (int i = args.length; i >= 0; i--) { +371 String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase(); +372 Set<RegisteredCommand> cmds = subCommands.get(checkSub); +373 +374 final int extraArgs = args.length - i; +375 if (!cmds.isEmpty()) { +376 RegisteredCommand cmd = null; +377 if (cmds.size() == 1) { +378 cmd = Iterables.getOnlyElement(cmds); +379 } else { +380 Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> { +381 int required = c.requiredResolvers; +382 int optional = c.optionalResolvers; +383 return extraArgs <= required + optional && (completion || extraArgs >= required); +384 }).sorted((c1, c2) -> { +385 int a = c1.requiredResolvers + c1.optionalResolvers; +386 int b = c2.requiredResolvers + c2.optionalResolvers; +387 +388 if (a == b) { +389 return 0; +390 } +391 return a < b ? 1 : -1; +392 }).findFirst(); +393 if (optCmd.isPresent()) { +394 cmd = optCmd.get(); +395 } +396 } +397 if (cmd != null) { +398 return new CommandSearch(cmd, i, checkSub); +399 } +400 } +401 } +402 return null; +403 } +404 +405 private void executeCommand(CommandOperationContext commandOperationContext, +406 CommandIssuer issuer, String[] args, RegisteredCommand cmd) { +407 if (cmd.hasPermission(issuer)) { +408 commandOperationContext.setRegisteredCommand(cmd); +409 if (checkPrecommand(commandOperationContext, cmd, issuer, args)) { +410 return; +411 } +412 List<String> sargs = Lists.newArrayList(args); +413 cmd.invoke(issuer, sargs); +414 } else { +415 issuer.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED); +416 } +417 } +418 +419 public boolean canExecute(CommandIssuer issuer, RegisteredCommand<?> cmd) { +420 return true; +421 } +422 +423 public List<String> tabComplete(CommandIssuer issuer, String commandLabel, String[] args) +424 throws IllegalArgumentException { +425 +426 commandLabel = commandLabel.toLowerCase(); +427 try { +428 CommandOperationContext commandOperationContext = preCommandOperation(issuer, commandLabel, args); 429 -430 String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); +430 final CommandSearch search = findSubCommand(args, true); 431 -432 final List<String> cmds = new ArrayList<>(); +432 String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase(); 433 -434 if (search != null) { -435 cmds.addAll(completeCommand(commandOperationContext, issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel)); -436 } else if (subCommands.get(UNKNOWN).size() == 1) { -437 cmds.addAll(completeCommand(commandOperationContext, issuer, Iterables.getOnlyElement(subCommands.get(UNKNOWN)), args, commandLabel)); -438 } -439 -440 for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) { -441 final String key = entry.getKey(); -442 if (key.startsWith(argString) && !UNKNOWN.equals(key) && !DEFAULT.equals(key)) { -443 final RegisteredCommand value = entry.getValue(); -444 if (!value.hasPermission(issuer)) { -445 continue; -446 } -447 String prefCommand = value.prefSubCommand; -448 -449 final String[] psplit = ACFPatterns.SPACE.split(prefCommand); -450 cmds.add(psplit[args.length - 1]); -451 } -452 } -453 -454 return filterTabComplete(args[args.length - 1], cmds); -455 } finally { -456 postCommandOperation(); -457 } -458 } -459 -460 private List<String> completeCommand(CommandOperationContext commandOperationContext, CommandIssuer issuer, RegisteredCommand cmd, String[] args, String commandLabel) { -461 if (!cmd.hasPermission(issuer) || args.length > cmd.requiredResolvers + cmd.optionalResolvers || args.length == 0 -462 || cmd.complete == null) { -463 return ImmutableList.of(); -464 } -465 -466 String[] completions = ACFPatterns.SPACE.split(cmd.complete); +434 final List<String> cmds = new ArrayList<>(); +435 +436 if (search != null) { +437 cmds.addAll(completeCommand(commandOperationContext, issuer, search.cmd, Arrays.copyOfRange(args, search.argIndex, args.length), commandLabel)); +438 } else if (subCommands.get(UNKNOWN).size() == 1) { +439 cmds.addAll(completeCommand(commandOperationContext, issuer, Iterables.getOnlyElement(subCommands.get(UNKNOWN)), args, commandLabel)); +440 } +441 +442 for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) { +443 final String key = entry.getKey(); +444 if (key.startsWith(argString) && !UNKNOWN.equals(key) && !DEFAULT.equals(key)) { +445 final RegisteredCommand value = entry.getValue(); +446 if (!value.hasPermission(issuer)) { +447 continue; +448 } +449 String prefCommand = value.prefSubCommand; +450 +451 final String[] psplit = ACFPatterns.SPACE.split(prefCommand); +452 cmds.add(psplit[args.length - 1]); +453 } +454 } +455 +456 return filterTabComplete(args[args.length - 1], cmds); +457 } finally { +458 postCommandOperation(); +459 } +460 } +461 +462 private List<String> completeCommand(CommandOperationContext commandOperationContext, CommandIssuer issuer, RegisteredCommand cmd, String[] args, String commandLabel) { +463 if (!cmd.hasPermission(issuer) || args.length > cmd.requiredResolvers + cmd.optionalResolvers || args.length == 0 +464 || cmd.complete == null) { +465 return ImmutableList.of(); +466 } 467 -468 List<String> cmds = manager.getCommandCompletions().of(commandOperationContext, cmd, issuer, completions, args); -469 return filterTabComplete(args[args.length-1], cmds); -470 } -471 -472 private static List<String> filterTabComplete(String arg, List<String> cmds) { -473 return cmds.stream() -474 .distinct() -475 .filter(cmd -> cmd != null && (arg.isEmpty() || ApacheCommonsLangUtil.startsWithIgnoreCase(cmd, arg))) -476 .collect(Collectors.toList()); -477 } -478 -479 -480 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { -481 final Set<RegisteredCommand> defs = subCommands.get(subcommand); -482 RegisteredCommand def = null; -483 if (!defs.isEmpty()) { -484 if (defs.size() == 1) { -485 def = defs.iterator().next(); -486 } -487 if (def != null) { -488 executeCommand(commandContext, issuer, args, def); -489 return true; -490 } -491 } -492 return false; -493 } -494 -495 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { -496 Method pre = this.preCommandHandler; -497 if (pre != null) { -498 try { -499 Class<?>[] types = pre.getParameterTypes(); -500 Object[] parameters = new Object[pre.getParameterCount()]; -501 for (int i = 0; i < parameters.length; i++) { -502 Class<?> type = types[i]; -503 Object issuerObject = issuer.getIssuer(); -504 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { -505 parameters[i] = issuerObject; -506 } else if (CommandIssuer.class.isAssignableFrom(type)) { -507 parameters[i] = issuer; -508 } else if (RegisteredCommand.class.isAssignableFrom(type)) { -509 parameters[i] = cmd; -510 } else if (String[].class.isAssignableFrom((type))) { -511 parameters[i] = args; -512 } else { -513 parameters[i] = null; -514 } -515 } -516 -517 return (boolean) pre.invoke(this, parameters); -518 } catch (IllegalAccessException | InvocationTargetException e) { -519 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); -520 } -521 } -522 return false; -523 } -524 -525 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -526 public CommandHelp getCommandHelp() { -527 return manager.generateCommandHelp(); -528 } -529 -530 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -531 public void showCommandHelp() { -532 getCommandHelp().showHelp(); -533 } -534 -535 public void help(Object issuer, String[] args) { -536 help(manager.getCommandIssuer(issuer), args); -537 } -538 public void help(CommandIssuer issuer, String[] args) { -539 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); -540 } -541 public void doHelp(Object issuer, String... args) { -542 doHelp(manager.getCommandIssuer(issuer), args); -543 } -544 public void doHelp(CommandIssuer issuer, String... args) { -545 help(issuer, args); -546 } -547 -548 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { -549 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, -550 "{command}", "/" + cmd.command, -551 "{syntax}", cmd.syntaxText -552 ); -553 } -554 -555 public boolean hasPermission(Object issuer) { -556 return hasPermission(manager.getCommandIssuer(issuer)); -557 } -558 -559 public boolean hasPermission(CommandIssuer issuer) { -560 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); -561 } -562 -563 public String getName() { -564 return commandName; -565 } -566 -567 public ExceptionHandler getExceptionHandler() { -568 return exceptionHandler; -569 } -570 -571 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { -572 this.exceptionHandler = exceptionHandler; -573 return this; -574 } -575 -576 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; +468 String[] completions = ACFPatterns.SPACE.split(cmd.complete); +469 +470 List<String> cmds = manager.getCommandCompletions().of(commandOperationContext, cmd, issuer, completions, args); +471 return filterTabComplete(args[args.length-1], cmds); +472 } +473 +474 private static List<String> filterTabComplete(String arg, List<String> cmds) { +475 return cmds.stream() +476 .distinct() +477 .filter(cmd -> cmd != null && (arg.isEmpty() || ApacheCommonsLangUtil.startsWithIgnoreCase(cmd, arg))) +478 .collect(Collectors.toList()); +479 } +480 +481 +482 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { +483 final Set<RegisteredCommand> defs = subCommands.get(subcommand); +484 RegisteredCommand def = null; +485 if (!defs.isEmpty()) { +486 if (defs.size() == 1) { +487 def = defs.iterator().next(); +488 } +489 if (def != null) { +490 executeCommand(commandContext, issuer, args, def); +491 return true; +492 } +493 } +494 return false; +495 } +496 +497 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { +498 Method pre = this.preCommandHandler; +499 if (pre != null) { +500 try { +501 Class<?>[] types = pre.getParameterTypes(); +502 Object[] parameters = new Object[pre.getParameterCount()]; +503 for (int i = 0; i < parameters.length; i++) { +504 Class<?> type = types[i]; +505 Object issuerObject = issuer.getIssuer(); +506 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { +507 parameters[i] = issuerObject; +508 } else if (CommandIssuer.class.isAssignableFrom(type)) { +509 parameters[i] = issuer; +510 } else if (RegisteredCommand.class.isAssignableFrom(type)) { +511 parameters[i] = cmd; +512 } else if (String[].class.isAssignableFrom((type))) { +513 parameters[i] = args; +514 } else { +515 parameters[i] = null; +516 } +517 } +518 +519 return (boolean) pre.invoke(this, parameters); +520 } catch (IllegalAccessException | InvocationTargetException e) { +521 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); +522 } +523 } +524 return false; +525 } +526 +527 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +528 public CommandHelp getCommandHelp() { +529 return manager.generateCommandHelp(); +530 } +531 +532 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +533 public void showCommandHelp() { +534 getCommandHelp().showHelp(); +535 } +536 +537 public void help(Object issuer, String[] args) { +538 help(manager.getCommandIssuer(issuer), args); +539 } +540 public void help(CommandIssuer issuer, String[] args) { +541 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); +542 } +543 public void doHelp(Object issuer, String... args) { +544 doHelp(manager.getCommandIssuer(issuer), args); +545 } +546 public void doHelp(CommandIssuer issuer, String... args) { +547 help(issuer, args); +548 } +549 +550 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { +551 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, +552 "{command}", "/" + cmd.command, +553 "{syntax}", cmd.syntaxText +554 ); +555 } +556 +557 public boolean hasPermission(Object issuer) { +558 return hasPermission(manager.getCommandIssuer(issuer)); +559 } +560 +561 public boolean hasPermission(CommandIssuer issuer) { +562 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); +563 } +564 +565 public String getName() { +566 return commandName; +567 } +568 +569 public ExceptionHandler getExceptionHandler() { +570 return exceptionHandler; +571 } +572 +573 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { +574 this.exceptionHandler = exceptionHandler; +575 return this; +576 } 577 -578 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { -579 this.cmd = cmd; -580 this.argIndex = argIndex; -581 this.checkSub = checkSub; -582 } -583 -584 String getCheckSub() { -585 return this.checkSub; -586 } -587 -588 @Override -589 public boolean equals(Object o) { -590 if (this == o) return true; -591 if (o == null || getClass() != o.getClass()) return false; -592 CommandSearch that = (CommandSearch) o; -593 return argIndex == that.argIndex && -594 Objects.equals(cmd, that.cmd) && -595 Objects.equals(checkSub, that.checkSub); -596 } -597 -598 @Override -599 public int hashCode() { -600 return Objects.hash(cmd, argIndex, checkSub); -601 } -602 } -603} +578 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; +579 +580 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { +581 this.cmd = cmd; +582 this.argIndex = argIndex; +583 this.checkSub = checkSub; +584 } +585 +586 String getCheckSub() { +587 return this.checkSub; +588 } +589 +590 @Override +591 public boolean equals(Object o) { +592 if (this == o) return true; +593 if (o == null || getClass() != o.getClass()) return false; +594 CommandSearch that = (CommandSearch) o; +595 return argIndex == that.argIndex && +596 Objects.equals(cmd, that.cmd) && +597 Objects.equals(checkSub, that.checkSub); +598 } +599 +600 @Override +601 public int hashCode() { +602 return Objects.hash(cmd, argIndex, checkSub); +603 } +604 } +605}