diff --git a/core/src/main/java/co/aikar/commands/CommandContexts.java b/core/src/main/java/co/aikar/commands/CommandContexts.java index c4ce6e02..3f6cf8f1 100644 --- a/core/src/main/java/co/aikar/commands/CommandContexts.java +++ b/core/src/main/java/co/aikar/commands/CommandContexts.java @@ -167,7 +167,11 @@ public class CommandContexts helpEntries = new ArrayList<>(); private int page; - private int perPage = 15; + private int perPage; private List search; public CommandHelp(CommandManager manager, RootCommand rootCommand, CommandIssuer issuer) { this.manager = manager; this.issuer = issuer; + this.perPage = manager.defaultHelpPerPage; SetMultimap subCommands = rootCommand.getSubCommands(); Set seen = new HashSet<>(); @@ -107,16 +107,23 @@ public class CommandHelp { } public void showHelp(CommandIssuer issuer, MessageKeyProvider format) { - Iterator results = getHelpEntries().stream() + List helpEntries = getHelpEntries(); + Iterator results = helpEntries.stream() .filter(HelpEntry::shouldShow) .sorted(Comparator.comparingInt(helpEntry -> helpEntry.getSearchScore() * -1)).iterator(); if (!results.hasNext()) { issuer.sendMessage(MessageType.ERROR, MessageKeys.NO_COMMAND_MATCHED_SEARCH, "{search}", ACFUtil.join(this.search, " ")); - results = getHelpEntries().iterator(); + helpEntries = getHelpEntries(); + results = helpEntries.iterator(); } + int totalResults = helpEntries.size(); int min = (this.page-1) * this.perPage; // TODO: per page configurable? int max = min + this.perPage; int i = 0; + if (min >= totalResults) { + issuer.sendMessage(MessageType.HELP, MessageKeys.HELP_NO_RESULTS); + return; + } while (results.hasNext()) { HelpEntry e = results.next(); @@ -132,6 +139,13 @@ public class CommandHelp { issuer.sendMessageInternal(ACFUtil.rtrim(msg)); } } + if (min > 0 || results.hasNext()) { + issuer.sendMessage(MessageType.HELP, MessageKeys.HELP_PAGE_INFORMATION, + "{page}", "" + this.page, + "{totalpages}", ""+ (int)Math.ceil((float)totalResults / (float)this.perPage), + "{results}", "" + totalResults + ); + } } /** @@ -154,9 +168,17 @@ public class CommandHelp { return helpEntries; } - public void setPage(int page, int perPage) { + public void setPerPage(int perPage) { + this.perPage = perPage; + } + + public void setPage(int page) { this.page = page; - this.perPage = 15; + } + + public void setPage(int page, int perPage) { + this.setPage(page); + this.setPerPage(perPage); } public void setSearch(List search) { diff --git a/core/src/main/java/co/aikar/commands/CommandManager.java b/core/src/main/java/co/aikar/commands/CommandManager.java index 681ac7d7..810c9a7c 100644 --- a/core/src/main/java/co/aikar/commands/CommandManager.java +++ b/core/src/main/java/co/aikar/commands/CommandManager.java @@ -52,6 +52,7 @@ public abstract class CommandManager > { protected Set supportedLanguages = Sets.newHashSet(Locales.ENGLISH, Locales.GERMAN, Locales.SPANISH, Locales.CZECH); protected Map formatters = new IdentityHashMap<>(); protected F defaultFormatter; + protected int defaultHelpPerPage = 10; private Set unstableAPIs = Sets.newHashSet(); public static CommandOperationContext getCurrentCommandOperationContext() { @@ -141,6 +142,18 @@ public abstract class CommandManager > { return new CommandHelp(this, rootCommand, issuer); } + /** @deprecated Unstable API */ @Deprecated @UnstableAPI + public int getDefaultHelpPerPage() { + verifyUnstableAPI("help"); + return defaultHelpPerPage; + } + + /** @deprecated Unstable API */ @Deprecated @UnstableAPI + public void setDefaultHelpPerPage(int defaultHelpPerPage) { + verifyUnstableAPI("help"); + this.defaultHelpPerPage = defaultHelpPerPage; + } + /** * Registers a command with ACF * diff --git a/core/src/main/java/co/aikar/commands/MessageKeys.java b/core/src/main/java/co/aikar/commands/MessageKeys.java index c0a2b416..e0440135 100644 --- a/core/src/main/java/co/aikar/commands/MessageKeys.java +++ b/core/src/main/java/co/aikar/commands/MessageKeys.java @@ -45,7 +45,10 @@ public enum MessageKeys implements MessageKeyProvider { NOT_ALLOWED_ON_CONSOLE, COULD_NOT_FIND_PLAYER, HELP_FORMAT, - NO_COMMAND_MATCHED_SEARCH; + NO_COMMAND_MATCHED_SEARCH, + HELP_PAGE_INFORMATION, + HELP_NO_RESULTS + ; private final MessageKey key = MessageKey.of("acf-core." + this.name().toLowerCase()); public MessageKey getMessageKey() { diff --git a/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html b/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html index 701e2fb3..9f7b6270 100644 --- a/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html +++ b/docs/acf-bukkit/co/aikar/commands/BukkitCommandManager.html @@ -164,7 +164,7 @@ extends co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,org

Fields inherited from class co.aikar.commands.CommandManager

-defaultExceptionHandler, defaultFormatter, formatters, replacements, rootCommands, supportedLanguages +defaultExceptionHandler, defaultFormatter, defaultHelpPerPage, formatters, replacements, rootCommands, supportedLanguages @@ -294,7 +294,7 @@ extends co.aikar.commands.CommandManager<org.bukkit.command.CommandSender,org

Methods inherited from class co.aikar.commands.CommandManager

-addSupportedLanguage, createCommandOperationContext, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setFormat, setFormat, setFormat +addSupportedLanguage, createCommandOperationContext, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getDefaultHelpPerPage, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setDefaultHelpPerPage, setFormat, setFormat, setFormat @@ -277,7 +277,7 @@ extends co.aikar.commands.CommandManager<net.md_5.bungee.api.CommandSender,ne

Methods inherited from class co.aikar.commands.CommandManager

-addSupportedLanguage, createCommandOperationContext, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setFormat, setFormat, setFormat +addSupportedLanguage, createCommandOperationContext, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getDefaultHelpPerPage, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setDefaultHelpPerPage, setFormat, setFormat, setFormat @@ -477,7 +481,7 @@ public 

showCommandHelp

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

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

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

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

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

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

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

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

    -
    public String getName()
    +
    public String getName()
  • @@ -564,16 +568,25 @@ public void 
  • getExceptionHandler

    -
    public ExceptionHandler getExceptionHandler()
    +
    public ExceptionHandler getExceptionHandler()
  • - diff --git a/docs/acf-core/co/aikar/commands/CommandHelp.html b/docs/acf-core/co/aikar/commands/CommandHelp.html index 87176c8e..7735a86d 100644 --- a/docs/acf-core/co/aikar/commands/CommandHelp.html +++ b/docs/acf-core/co/aikar/commands/CommandHelp.html @@ -18,7 +18,7 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10}; +var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10}; var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; @@ -109,7 +109,7 @@ var activeTableTab = "activeTableTab";


  • -
    public class CommandHelp
    +
    public class CommandHelp
     extends Object
  • @@ -168,22 +168,31 @@ extends void -setSearch(List<String> search)  +setPage(int page, + int perPage)  void -showHelp()  +setPerPage(int perPage)  void -showHelp(CommandIssuer issuer)  +setSearch(List<String> search)  void +showHelp()  + + +void +showHelp(CommandIssuer issuer)  + + +void showHelp(CommandIssuer issuer, co.aikar.locales.MessageKeyProvider format)  - + protected void updateSearchScore(HelpEntry help)  @@ -234,7 +243,7 @@ extends
  • updateSearchScore

    -
    protected void updateSearchScore(HelpEntry help)
    +
    protected void updateSearchScore(HelpEntry help)
  • @@ -243,7 +252,7 @@ extends
  • getManager

    -
    public CommandManager getManager()
    +
    public CommandManager getManager()
  • @@ -252,7 +261,7 @@ extends
  • showHelp

    -
    public void showHelp()
    +
    public void showHelp()
  • @@ -261,7 +270,7 @@ extends
  • showHelp

    -
    public void showHelp(CommandIssuer issuer)
    +
    public void showHelp(CommandIssuer issuer)
  • @@ -270,7 +279,7 @@ extends
  • showHelp

    -
    public void showHelp(CommandIssuer issuer,
    +
    public void showHelp(CommandIssuer issuer,
                          co.aikar.locales.MessageKeyProvider format)
  • @@ -281,7 +290,7 @@ extends

    getFormatReplacements

    @NotNull
    -public @NotNull String[] getFormatReplacements(HelpEntry e)
    +public @NotNull String[] getFormatReplacements(HelpEntry e)
    Override this to control replacements
    Parameters:
    @@ -296,7 +305,16 @@ public @NotNull
  • getHelpEntries

    -
    public List<HelpEntrygetHelpEntries()
    +
    public List<HelpEntrygetHelpEntries()
    +
  • + + + + +
      +
    • +

      setPerPage

      +
      public void setPerPage(int perPage)
    @@ -305,7 +323,17 @@ public @NotNull
  • setPage

    -
    public void setPage(int page)
    +
    public void setPage(int page)
    +
  • + + + + +
      +
    • +

      setPage

      +
      public void setPage(int page,
      +                    int perPage)
    @@ -314,7 +342,7 @@ public @NotNull
  • setSearch

    -
    public void setSearch(List<String> search)
    +
    public void setSearch(List<String> search)
  • diff --git a/docs/acf-core/co/aikar/commands/CommandManager.html b/docs/acf-core/co/aikar/commands/CommandManager.html index cba7d3b6..05677a7d 100644 --- a/docs/acf-core/co/aikar/commands/CommandManager.html +++ b/docs/acf-core/co/aikar/commands/CommandManager.html @@ -18,7 +18,7 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":6,"i2":10,"i3":6,"i4":10,"i5":6,"i6":42,"i7":10,"i8":42,"i9":42,"i10":42,"i11":42,"i12":6,"i13":6,"i14":6,"i15":10,"i16":9,"i17":9,"i18":9,"i19":10,"i20":10,"i21":10,"i22":10,"i23":6,"i24":10,"i25":10,"i26":10,"i27":6,"i28":6,"i29":10,"i30":6,"i31":10,"i32":6,"i33":10,"i34":10,"i35":10,"i36":10,"i37":10,"i38":10,"i39":10}; +var methods = {"i0":10,"i1":6,"i2":10,"i3":6,"i4":10,"i5":6,"i6":42,"i7":10,"i8":42,"i9":42,"i10":42,"i11":42,"i12":6,"i13":6,"i14":6,"i15":10,"i16":9,"i17":9,"i18":9,"i19":10,"i20":10,"i21":42,"i22":10,"i23":10,"i24":6,"i25":10,"i26":10,"i27":10,"i28":6,"i29":6,"i30":10,"i31":6,"i32":10,"i33":6,"i34":10,"i35":10,"i36":10,"i37":10,"i38":42,"i39":10,"i40":10,"i41":10}; var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],4:["t3","Abstract Methods"],8:["t4","Concrete Methods"],32:["t6","Deprecated Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; @@ -138,18 +138,22 @@ extends defaultFormatter  +protected int +defaultHelpPerPage  + + protected Map<MessageType,F> formatters  - + protected CommandReplacements replacements  - + protected Map<String,co.aikar.commands.RootCommand> rootCommands  - + protected Set<Locale> supportedLanguages  @@ -322,26 +326,34 @@ extends getDefaultFormatter()  +int +getDefaultHelpPerPage() +
    Deprecated.  +
    Unstable API
    +
    + + + F getFormat(MessageType type)  - + Locale getIssuerLocale(CommandIssuer issuer)  - + abstract Locales getLocales()
    Returns a Locales Manager to add and modify language tables for your commands.
    - + Set<Locale> getSupportedLanguages()
    Gets a list of all currently supported languages for this manager.
    - + protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, @@ -349,75 +361,83 @@ extends List<String> args, Throwable t)  - + boolean hasPermission(CommandIssuer issuer, String permission)  - + abstract boolean hasRegisteredCommands()  - + abstract boolean isCommandIssuer(Class<?> type)  - + void log(co.aikar.commands.LogLevel level, String message)  - + abstract void log(co.aikar.commands.LogLevel level, String message, Throwable throwable)  - + co.aikar.commands.RootCommand obtainRootCommand(String cmd)  - + abstract void registerCommand(BaseCommand command)
    Registers a command with ACF
    - + void sendMessage(CommandIssuer issuer, MessageType type, co.aikar.locales.MessageKeyProvider key, String... replacements)  - + void sendMessage(I issuerArg, MessageType type, co.aikar.locales.MessageKeyProvider key, String... replacements)  - + void setDefaultExceptionHandler(ExceptionHandler exceptionHandler)
    Sets the default ExceptionHandler that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered.
    - + void setDefaultFormatter(F defaultFormatter)  - + +void +setDefaultHelpPerPage(int defaultHelpPerPage) +
    Deprecated.  +
    Unstable API
    +
    + + + F setFormat(MessageType type, F formatter)  - + void setFormat(MessageType type, FT... colors)  - + void setFormat(MessageType type, int i, @@ -493,12 +513,21 @@ extends - @@ -530,7 +559,7 @@ extends
  • getCurrentCommandOperationContext

    -
    public static CommandOperationContext getCurrentCommandOperationContext()
    +
    public static CommandOperationContext getCurrentCommandOperationContext()
  • @@ -539,7 +568,7 @@ extends
  • getCurrentCommandIssuer

    -
    public static CommandIssuer getCurrentCommandIssuer()
    +
    public static CommandIssuer getCurrentCommandIssuer()
  • @@ -548,7 +577,7 @@ extends
  • getCurrentCommandManager

    -
    public static CommandManager getCurrentCommandManager()
    +
    public static CommandManager getCurrentCommandManager()
  • @@ -559,7 +588,7 @@ extends
  • setFormat

    -
    public F setFormat(MessageType type,
    +
    public F setFormat(MessageType type,
                        F formatter)
  • @@ -569,7 +598,7 @@ extends
  • getFormat

    -
    public F getFormat(MessageType type)
    +
    public F getFormat(MessageType type)
  • @@ -580,7 +609,7 @@ extends
  • setFormat

    -
    public void setFormat(MessageType type,
    +
    public void setFormat(MessageType type,
                           FT... colors)
  • @@ -592,7 +621,7 @@ extends
  • setFormat

    -
    public void setFormat(MessageType type,
    +
    public void setFormat(MessageType type,
                           int i,
                           FT color)
  • @@ -603,7 +632,7 @@ extends
  • getDefaultFormatter

    -
    public F getDefaultFormatter()
    +
    public F getDefaultFormatter()
  • @@ -614,7 +643,7 @@ extends
  • setDefaultFormatter

    -
    public void setDefaultFormatter(F defaultFormatter)
    +
    public void setDefaultFormatter(F defaultFormatter)
  • @@ -623,7 +652,7 @@ extends
  • getCommandContexts

    -
    public abstract CommandContexts<?> getCommandContexts()
    +
    public abstract CommandContexts<?> getCommandContexts()
    Gets the command contexts manager
    Returns:
    @@ -637,7 +666,7 @@ extends
  • getCommandCompletions

    -
    public abstract CommandCompletions<?> getCommandCompletions()
    +
    public abstract CommandCompletions<?> getCommandCompletions()
    Gets the command completions manager
    Returns:
    @@ -652,7 +681,7 @@ extends

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp(@NotNull
    +public CommandHelp generateCommandHelp(@NotNull
                                                        @NotNull String command)
    Deprecated. Unstable API
  • @@ -664,7 +693,7 @@ public 

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp(CommandIssuer issuer,
    +public CommandHelp generateCommandHelp(CommandIssuer issuer,
                                                        @NotNull
                                                        @NotNull String command)
    Deprecated. Unstable API
    @@ -677,7 +706,7 @@ public 

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp()
    +public CommandHelp generateCommandHelp()
    Deprecated. Unstable API
  • @@ -688,18 +717,40 @@ public 

    generateCommandHelp

    @Deprecated
    -public CommandHelp generateCommandHelp(CommandIssuer issuer,
    +public CommandHelp generateCommandHelp(CommandIssuer issuer,
                                                        co.aikar.commands.RootCommand rootCommand)
    Deprecated. Unstable API
    + + + + + + + + @@ -722,7 +773,7 @@ public 
  • isCommandIssuer

    -
    public abstract boolean isCommandIssuer(Class<?> type)
    +
    public abstract boolean isCommandIssuer(Class<?> type)
  • @@ -731,7 +782,7 @@ public 
  • getCommandIssuer

    -
    public abstract CommandIssuer getCommandIssuer(Object issuer)
    +
    public abstract CommandIssuer getCommandIssuer(Object issuer)
  • @@ -740,7 +791,7 @@ public 
  • createRootCommand

    -
    public abstract co.aikar.commands.RootCommand createRootCommand(String cmd)
    +
    public abstract co.aikar.commands.RootCommand createRootCommand(String cmd)
  • @@ -749,7 +800,7 @@ public 
  • getLocales

    -
    public abstract Locales getLocales()
    +
    public abstract Locales getLocales()
    Returns a Locales Manager to add and modify language tables for your commands.
    Returns:
    @@ -762,7 +813,7 @@ public 
  • createCommandContext

    -
    public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command,
    +
    public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command,
                                                                                Parameter parameter,
                                                                                CommandIssuer sender,
                                                                                List<String> args,
    @@ -776,7 +827,7 @@ public 
     
  • createCompletionContext

    -
    public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command,
    +
    public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command,
                                                                      CommandIssuer sender,
                                                                      String input,
                                                                      String config,
    @@ -789,7 +840,7 @@ public 
     
  • log

    -
    public abstract void log(co.aikar.commands.LogLevel level,
    +
    public abstract void log(co.aikar.commands.LogLevel level,
                              String message,
                              Throwable throwable)
  • @@ -800,7 +851,7 @@ public 
  • log

    -
    public void log(co.aikar.commands.LogLevel level,
    +
    public void log(co.aikar.commands.LogLevel level,
                     String message)
  • @@ -810,7 +861,7 @@ public 
  • getCommandReplacements

    -
    public CommandReplacements getCommandReplacements()
    +
    public CommandReplacements getCommandReplacements()
    Lets you add custom string replacements that can be applied to annotation values, to reduce duplication/repetition of common values such as permission nodes and command prefixes. @@ -829,7 +880,7 @@ public 
  • hasPermission

    -
    public boolean hasPermission(CommandIssuer issuer,
    +
    public boolean hasPermission(CommandIssuer issuer,
                                  String permission)
  • @@ -839,7 +890,7 @@ public 
  • obtainRootCommand

    -
    public co.aikar.commands.RootCommand obtainRootCommand(String cmd)
    +
    public co.aikar.commands.RootCommand obtainRootCommand(String cmd)
  • @@ -848,7 +899,7 @@ public 
  • createRegisteredCommand

    -
    public RegisteredCommand createRegisteredCommand(BaseCommand command,
    +
    public RegisteredCommand createRegisteredCommand(BaseCommand command,
                                                      String cmdName,
                                                      Method method,
                                                      String prefSubCommand)
    @@ -860,7 +911,7 @@ public 
  • setDefaultExceptionHandler

    -
    public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler)
    +
    public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler)
    Sets the default ExceptionHandler that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered.
    Parameters:
    @@ -874,7 +925,7 @@ public 
  • getDefaultExceptionHandler

    -
    public ExceptionHandler getDefaultExceptionHandler()
    +
    public ExceptionHandler getDefaultExceptionHandler()
    Gets the current default exception handler, might be null.
    Returns:
    @@ -888,7 +939,7 @@ public 
  • handleUncaughtException

    -
    protected boolean handleUncaughtException(BaseCommand scope,
    +
    protected boolean handleUncaughtException(BaseCommand scope,
                                               RegisteredCommand registeredCommand,
                                               CommandIssuer sender,
                                               List<String> args,
    @@ -903,7 +954,7 @@ public 
     
  • sendMessage

    -
    public void sendMessage(I issuerArg,
    +
    public void sendMessage(I issuerArg,
                             MessageType type,
                             co.aikar.locales.MessageKeyProvider key,
                             String... replacements)
    @@ -915,7 +966,7 @@ public 
  • sendMessage

    -
    public void sendMessage(CommandIssuer issuer,
    +
    public void sendMessage(CommandIssuer issuer,
                             MessageType type,
                             co.aikar.locales.MessageKeyProvider key,
                             String... replacements)
    @@ -927,7 +978,7 @@ public 
  • formatMessage

    -
    public String formatMessage(CommandIssuer issuer,
    +
    public String formatMessage(CommandIssuer issuer,
                                 MessageType type,
                                 co.aikar.locales.MessageKeyProvider key,
                                 String... replacements)
    @@ -939,7 +990,7 @@ public 
  • getIssuerLocale

    -
    public Locale getIssuerLocale(CommandIssuer issuer)
    +
    public Locale getIssuerLocale(CommandIssuer issuer)
  • @@ -948,7 +999,7 @@ public 
  • createCommandOperationContext

    -
    public CommandOperationContext createCommandOperationContext(BaseCommand command,
    +
    public CommandOperationContext createCommandOperationContext(BaseCommand command,
                                                                  CommandIssuer issuer,
                                                                  String commandLabel,
                                                                  String[] args)
    @@ -960,7 +1011,7 @@ public 
  • getSupportedLanguages

    -
    public Set<LocalegetSupportedLanguages()
    +
    public Set<LocalegetSupportedLanguages()
    Gets a list of all currently supported languages for this manager. These locales will be automatically loaded from
    @@ -974,7 +1025,7 @@ public 
  • addSupportedLanguage

    -
    public void addSupportedLanguage(Locale locale)
    +
    public void addSupportedLanguage(Locale locale)
    Adds a new locale to the list of automatic Locales to load Message Bundles for. All bundles loaded under the previous supported languages will now automatically load for this new locale too.
    @@ -990,7 +1041,7 @@ public 

    enableUnstableAPI

    @Deprecated
    -public void enableUnstableAPI(String api)
    +public void enableUnstableAPI(String api)
  • Deprecated. Use this with caution! If you enable and use Unstable API's, your next compile using ACF may require you to update your implementation to those unstable API's
  • diff --git a/docs/acf-core/co/aikar/commands/ForwardingCommand.html b/docs/acf-core/co/aikar/commands/ForwardingCommand.html index 55e10a89..88c701c1 100644 --- a/docs/acf-core/co/aikar/commands/ForwardingCommand.html +++ b/docs/acf-core/co/aikar/commands/ForwardingCommand.html @@ -171,7 +171,7 @@ extends BaseCommand -canExecute, doHelp, doHelp, getCommandHelp, getCurrentCommandIssuer, getCurrentCommandManager, getExceptionHandler, getExecCommandLabel, getExecSubcommand, getName, getOrigArgs, hasPermission, help, help, setExceptionHandler, showCommandHelp, showSyntax
  • +canExecute, doHelp, doHelp, getCommandHelp, getCurrentCommandIssuer, getCurrentCommandManager, getDefaultRegisteredCommand, getExceptionHandler, getExecCommandLabel, getExecSubcommand, getName, getOrigArgs, hasPermission, help, help, setExceptionHandler, showCommandHelp, showSyntax
  • HELP_FORMAT  +HELP_NO_RESULTS  + + +HELP_PAGE_INFORMATION  + + INFO_MESSAGE  @@ -374,12 +380,30 @@ the order they are declared. - @@ -436,7 +460,7 @@ not permitted.)
    • getMessageKey

      -
      public co.aikar.locales.MessageKey getMessageKey()
      +
      public co.aikar.locales.MessageKey getMessageKey()
      Specified by:
      getMessageKey in interface co.aikar.locales.MessageKeyProvider
      diff --git a/docs/acf-core/co/aikar/commands/annotation/package-tree.html b/docs/acf-core/co/aikar/commands/annotation/package-tree.html index ff09441a..e684884e 100644 --- a/docs/acf-core/co/aikar/commands/annotation/package-tree.html +++ b/docs/acf-core/co/aikar/commands/annotation/package-tree.html @@ -79,22 +79,22 @@

      Annotation Type Hierarchy

      diff --git a/docs/acf-core/co/aikar/commands/class-use/CommandIssuer.html b/docs/acf-core/co/aikar/commands/class-use/CommandIssuer.html index 65414c59..841254ba 100644 --- a/docs/acf-core/co/aikar/commands/class-use/CommandIssuer.html +++ b/docs/acf-core/co/aikar/commands/class-use/CommandIssuer.html @@ -153,13 +153,13 @@ CommandManager.getCommandIssuer(Object issuer)  -static CommandIssuer -CommandManager.getCurrentCommandIssuer()  - - CommandIssuer BaseCommand.getCurrentCommandIssuer()  + +static CommandIssuer +CommandManager.getCurrentCommandIssuer()  + CommandIssuer CommandCompletionContext.getIssuer()  @@ -221,13 +221,13 @@ void -ForwardingCommand.execute(CommandIssuer issuer, +BaseCommand.execute(CommandIssuer issuer, String commandLabel, String[] args)  void -BaseCommand.execute(CommandIssuer issuer, +ForwardingCommand.execute(CommandIssuer issuer, String commandLabel, String[] args)  @@ -275,11 +275,11 @@ boolean -ForwardingCommand.hasPermission(CommandIssuer sender)  +BaseCommand.hasPermission(CommandIssuer issuer)  boolean -BaseCommand.hasPermission(CommandIssuer issuer)  +ForwardingCommand.hasPermission(CommandIssuer sender)  boolean @@ -314,14 +314,14 @@ List<String> -ForwardingCommand.tabComplete(CommandIssuer issuer, - String alias, +BaseCommand.tabComplete(CommandIssuer issuer, + String commandLabel, String[] args)  List<String> -BaseCommand.tabComplete(CommandIssuer issuer, - String commandLabel, +ForwardingCommand.tabComplete(CommandIssuer issuer, + String alias, String[] args)  diff --git a/docs/acf-core/co/aikar/commands/class-use/CommandManager.html b/docs/acf-core/co/aikar/commands/class-use/CommandManager.html index 72818ad4..2b3ab3ad 100644 --- a/docs/acf-core/co/aikar/commands/class-use/CommandManager.html +++ b/docs/acf-core/co/aikar/commands/class-use/CommandManager.html @@ -120,20 +120,20 @@ CommandOperationContext.getCommandManager()  -static CommandManager -CommandManager.getCurrentCommandManager()  - - CommandManager BaseCommand.getCurrentCommandManager()  + +static CommandManager +CommandManager.getCurrentCommandManager()  + CommandManager -CommandIssuer.getManager()  +CommandHelp.getManager()  CommandManager -CommandHelp.getManager()  +CommandIssuer.getManager()  diff --git a/docs/acf-core/co/aikar/commands/class-use/RegisteredCommand.html b/docs/acf-core/co/aikar/commands/class-use/RegisteredCommand.html index d7f4e02c..b3a67438 100644 --- a/docs/acf-core/co/aikar/commands/class-use/RegisteredCommand.html +++ b/docs/acf-core/co/aikar/commands/class-use/RegisteredCommand.html @@ -115,6 +115,10 @@ RegisteredCommand +BaseCommand.getDefaultRegisteredCommand()  + + +RegisteredCommand CommandOperationContext.getRegisteredCommand()  diff --git a/docs/acf-core/co/aikar/commands/class-use/UnstableAPI.html b/docs/acf-core/co/aikar/commands/class-use/UnstableAPI.html index 0f659363..e91e37bc 100644 --- a/docs/acf-core/co/aikar/commands/class-use/UnstableAPI.html +++ b/docs/acf-core/co/aikar/commands/class-use/UnstableAPI.html @@ -145,6 +145,22 @@ +int +CommandManager.getDefaultHelpPerPage() +
      Deprecated.  +
      Unstable API
      +
      + + + +void +CommandManager.setDefaultHelpPerPage(int defaultHelpPerPage) +
      Deprecated.  +
      Unstable API
      +
      + + + void BaseCommand.showCommandHelp()
      Deprecated.  diff --git a/docs/acf-core/deprecated-list.html b/docs/acf-core/deprecated-list.html index b3885c29..83b0897a 100644 --- a/docs/acf-core/deprecated-list.html +++ b/docs/acf-core/deprecated-list.html @@ -160,19 +160,29 @@ -co.aikar.commands.ACFUtil.random(Class<? extends T>) +co.aikar.commands.CommandManager.getDefaultHelpPerPage() +
      Unstable API
      + +co.aikar.commands.ACFUtil.random(Class<? extends T>) + + co.aikar.commands.CommandContexts.registerSenderAwareContext(Class<T>, IssuerAwareContextResolver<T, R>)
      Please switch to CommandContexts.registerIssuerAwareContext(Class, IssuerAwareContextResolver) as the core wants to use the platform agnostic term of "Issuer" instead of Sender
      - + co.aikar.commands.CommandIssuer.sendMessageInternal(String)
      Do not call this, for internal use. Not considered part of the API and may break.
      + +co.aikar.commands.CommandManager.setDefaultHelpPerPage(int) +
      Unstable API
      + + co.aikar.commands.BaseCommand.showCommandHelp()
      Unstable API
      diff --git a/docs/acf-core/index-all.html b/docs/acf-core/index-all.html index ff58a63d..37dd2de4 100644 --- a/docs/acf-core/index-all.html +++ b/docs/acf-core/index-all.html @@ -272,6 +272,8 @@
       
      defaultFormatter - Variable in class co.aikar.commands.CommandManager
       
      +
      defaultHelpPerPage - Variable in class co.aikar.commands.CommandManager
      +
       
      Description - Annotation Type in co.aikar.commands.annotation
       
      doHelp(Object, String...) - Method in class co.aikar.commands.BaseCommand
      @@ -469,8 +471,16 @@
      getDefaultFormatter() - Method in class co.aikar.commands.CommandManager
       
      +
      getDefaultHelpPerPage() - Method in class co.aikar.commands.CommandManager
      +
      +
      Deprecated. +
      Unstable API
      +
      +
      getDefaultLocale() - Method in class co.aikar.commands.Locales
       
      +
      getDefaultRegisteredCommand() - Method in class co.aikar.commands.BaseCommand
      +
       
      getDescription() - Method in class co.aikar.commands.HelpEntry
       
      getEnumFromName(T[], String) - Static method in class co.aikar.commands.ACFUtil
      @@ -1268,6 +1278,12 @@
      setDefaultFormatter(F) - Method in class co.aikar.commands.CommandManager
       
      +
      setDefaultHelpPerPage(int) - Method in class co.aikar.commands.CommandManager
      +
      +
      Deprecated. +
      Unstable API
      +
      +
      setDefaultLocale(Locale) - Method in class co.aikar.commands.Locales
       
      setExceptionHandler(ExceptionHandler) - Method in class co.aikar.commands.BaseCommand
      @@ -1280,6 +1296,10 @@
       
      setPage(int) - Method in class co.aikar.commands.CommandHelp
       
      +
      setPage(int, int) - Method in class co.aikar.commands.CommandHelp
      +
       
      +
      setPerPage(int) - Method in class co.aikar.commands.CommandHelp
      +
       
      setRegisteredCommand(RegisteredCommand) - Method in class co.aikar.commands.CommandOperationContext
       
      setSearch(List<String>) - Method in class co.aikar.commands.CommandHelp
      diff --git a/docs/acf-core/overview-tree.html b/docs/acf-core/overview-tree.html index b0c06e99..0ccdcff2 100644 --- a/docs/acf-core/overview-tree.html +++ b/docs/acf-core/overview-tree.html @@ -144,22 +144,22 @@

      Annotation Type Hierarchy

      Enum Hierarchy

        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 a64ab518..17c68b85 100644 --- a/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html +++ b/docs/acf-core/src-html/co/aikar/commands/BaseCommand.html @@ -487,131 +487,141 @@ 479 .collect(Collectors.toList()); 480 } 481 -482 -483 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { -484 final Set<RegisteredCommand> defs = subCommands.get(subcommand); -485 RegisteredCommand def = null; -486 if (!defs.isEmpty()) { -487 if (defs.size() == 1) { -488 def = defs.iterator().next(); -489 } -490 if (def != null) { -491 executeCommand(commandContext, issuer, args, def); -492 return true; -493 } -494 } -495 return false; -496 } -497 -498 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { -499 Method pre = this.preCommandHandler; -500 if (pre != null) { -501 try { -502 Class<?>[] types = pre.getParameterTypes(); -503 Object[] parameters = new Object[pre.getParameterCount()]; -504 for (int i = 0; i < parameters.length; i++) { -505 Class<?> type = types[i]; -506 Object issuerObject = issuer.getIssuer(); -507 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { -508 parameters[i] = issuerObject; -509 } else if (CommandIssuer.class.isAssignableFrom(type)) { -510 parameters[i] = issuer; -511 } else if (RegisteredCommand.class.isAssignableFrom(type)) { -512 parameters[i] = cmd; -513 } else if (String[].class.isAssignableFrom((type))) { -514 parameters[i] = args; -515 } else { -516 parameters[i] = null; -517 } -518 } -519 -520 return (boolean) pre.invoke(this, parameters); -521 } catch (IllegalAccessException | InvocationTargetException e) { -522 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); -523 } -524 } -525 return false; -526 } -527 -528 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -529 public CommandHelp getCommandHelp() { -530 return manager.generateCommandHelp(); -531 } -532 -533 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -534 public void showCommandHelp() { -535 getCommandHelp().showHelp(); -536 } -537 -538 public void help(Object issuer, String[] args) { -539 help(manager.getCommandIssuer(issuer), args); -540 } -541 public void help(CommandIssuer issuer, String[] args) { -542 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); -543 } -544 public void doHelp(Object issuer, String... args) { -545 doHelp(manager.getCommandIssuer(issuer), args); +482 RegisteredCommand getSubcommand(String subcommand) { +483 return getSubcommand(subcommand, false); +484 } +485 +486 RegisteredCommand getSubcommand(String subcommand, boolean requireOne) { +487 final Set<RegisteredCommand> commands = subCommands.get(subcommand); +488 if (!commands.isEmpty() && (!requireOne || commands.size() == 1)) { +489 return commands.iterator().next(); +490 } +491 return null; +492 } +493 +494 private boolean executeSubcommand(CommandOperationContext commandContext, String subcommand, CommandIssuer issuer, String... args) { +495 final RegisteredCommand cmd = this.getSubcommand(subcommand); +496 if (cmd != null) { +497 executeCommand(commandContext, issuer, args, cmd); +498 return true; +499 } +500 +501 return false; +502 } +503 +504 private boolean checkPrecommand(CommandOperationContext commandOperationContext, RegisteredCommand cmd, CommandIssuer issuer, String[] args) { +505 Method pre = this.preCommandHandler; +506 if (pre != null) { +507 try { +508 Class<?>[] types = pre.getParameterTypes(); +509 Object[] parameters = new Object[pre.getParameterCount()]; +510 for (int i = 0; i < parameters.length; i++) { +511 Class<?> type = types[i]; +512 Object issuerObject = issuer.getIssuer(); +513 if (manager.isCommandIssuer(type) && type.isAssignableFrom(issuerObject.getClass())) { +514 parameters[i] = issuerObject; +515 } else if (CommandIssuer.class.isAssignableFrom(type)) { +516 parameters[i] = issuer; +517 } else if (RegisteredCommand.class.isAssignableFrom(type)) { +518 parameters[i] = cmd; +519 } else if (String[].class.isAssignableFrom((type))) { +520 parameters[i] = args; +521 } else { +522 parameters[i] = null; +523 } +524 } +525 +526 return (boolean) pre.invoke(this, parameters); +527 } catch (IllegalAccessException | InvocationTargetException e) { +528 this.manager.log(LogLevel.ERROR, "Exception encountered while command pre-processing", e); +529 } +530 } +531 return false; +532 } +533 +534 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +535 public CommandHelp getCommandHelp() { +536 return manager.generateCommandHelp(); +537 } +538 +539 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +540 public void showCommandHelp() { +541 getCommandHelp().showHelp(); +542 } +543 +544 public void help(Object issuer, String[] args) { +545 help(manager.getCommandIssuer(issuer), args); 546 } -547 public void doHelp(CommandIssuer issuer, String... args) { -548 help(issuer, args); +547 public void help(CommandIssuer issuer, String[] args) { +548 issuer.sendMessage(MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND); 549 } -550 -551 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { -552 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, -553 "{command}", "/" + cmd.command, -554 "{syntax}", cmd.syntaxText -555 ); -556 } -557 -558 public boolean hasPermission(Object issuer) { -559 return hasPermission(manager.getCommandIssuer(issuer)); -560 } -561 -562 public boolean hasPermission(CommandIssuer issuer) { -563 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); -564 } -565 -566 public String getName() { -567 return commandName; -568 } -569 -570 public ExceptionHandler getExceptionHandler() { -571 return exceptionHandler; -572 } -573 -574 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { -575 this.exceptionHandler = exceptionHandler; -576 return this; -577 } -578 -579 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; -580 -581 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { -582 this.cmd = cmd; -583 this.argIndex = argIndex; -584 this.checkSub = checkSub; -585 } -586 -587 String getCheckSub() { -588 return this.checkSub; -589 } +550 public void doHelp(Object issuer, String... args) { +551 doHelp(manager.getCommandIssuer(issuer), args); +552 } +553 public void doHelp(CommandIssuer issuer, String... args) { +554 help(issuer, args); +555 } +556 +557 public void showSyntax(CommandIssuer issuer, RegisteredCommand<?> cmd) { +558 issuer.sendMessage(MessageType.SYNTAX, MessageKeys.INVALID_SYNTAX, +559 "{command}", "/" + cmd.command, +560 "{syntax}", cmd.syntaxText +561 ); +562 } +563 +564 public boolean hasPermission(Object issuer) { +565 return hasPermission(manager.getCommandIssuer(issuer)); +566 } +567 +568 public boolean hasPermission(CommandIssuer issuer) { +569 return permission == null || permission.isEmpty() || (manager.hasPermission(issuer, permission) && (parentCommand == null || parentCommand.hasPermission(issuer))); +570 } +571 +572 public String getName() { +573 return commandName; +574 } +575 +576 public ExceptionHandler getExceptionHandler() { +577 return exceptionHandler; +578 } +579 +580 public BaseCommand setExceptionHandler(ExceptionHandler exceptionHandler) { +581 this.exceptionHandler = exceptionHandler; +582 return this; +583 } +584 +585 public RegisteredCommand getDefaultRegisteredCommand() { +586 return this.getSubcommand(DEFAULT); +587 } +588 +589 private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; 590 -591 @Override -592 public boolean equals(Object o) { -593 if (this == o) return true; -594 if (o == null || getClass() != o.getClass()) return false; -595 CommandSearch that = (CommandSearch) o; -596 return argIndex == that.argIndex && -597 Objects.equals(cmd, that.cmd) && -598 Objects.equals(checkSub, that.checkSub); +591 CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) { +592 this.cmd = cmd; +593 this.argIndex = argIndex; +594 this.checkSub = checkSub; +595 } +596 +597 String getCheckSub() { +598 return this.checkSub; 599 } 600 601 @Override -602 public int hashCode() { -603 return Objects.hash(cmd, argIndex, checkSub); -604 } -605 } -606} +602 public boolean equals(Object o) { +603 if (this == o) return true; +604 if (o == null || getClass() != o.getClass()) return false; +605 CommandSearch that = (CommandSearch) o; +606 return argIndex == that.argIndex && +607 Objects.equals(cmd, that.cmd) && +608 Objects.equals(checkSub, that.checkSub); +609 } +610 +611 @Override +612 public int hashCode() { +613 return Objects.hash(cmd, argIndex, checkSub); +614 } +615 } +616} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html b/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html index c20f9526..6f6e758c 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandContexts.html @@ -176,72 +176,76 @@ 168 } 169 CommandHelp commandHelp = manager.generateCommandHelp(); 170 commandHelp.setPage(page); -171 commandHelp.setSearch(search); -172 return commandHelp; -173 }); -174 } -175 -176 /** -177 * @deprecated Please switch to {@link #registerIssuerAwareContext(Class, IssuerAwareContextResolver)} -178 * as the core wants to use the platform agnostic term of "Issuer" instead of Sender -179 * @see #registerIssuerAwareContext(Class, IssuerAwareContextResolver) -180 */ -181 @Deprecated -182 public <T> void registerSenderAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { -183 contextMap.put(context, supplier); -184 } -185 -186 /** -187 * Registers a context resolver that may conditionally consume input, falling back to using the context of the -188 * issuer to potentially fulfill this context. -189 * You may call {@link CommandExecutionContext#getFirstArg()} and then conditionally call {@link CommandExecutionContext#popFirstArg()} -190 * if you want to consume that input. -191 */ -192 public <T> void registerIssuerAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { -193 contextMap.put(context, supplier); -194 } -195 -196 /** -197 * Registers a context resolver that will never consume input. It will always satisfy its context based on the -198 * issuer of the command, so it will not appear in syntax strings. -199 */ -200 public <T> void registerIssuerOnlyContext(Class<T> context, IssuerOnlyContextResolver<T, R> supplier) { -201 contextMap.put(context, supplier); -202 } -203 -204 /** -205 * Registers a context that can safely accept a null input from the command issuer to resolve. This resolver should always -206 * call {@link CommandExecutionContext#popFirstArg()} -207 */ -208 public <T> void registerOptionalContext(Class<T> context, OptionalContextResolver<T, R> supplier) { -209 contextMap.put(context, supplier); -210 } -211 -212 /** -213 * Registers a context that requires input from the command issuer to resolve. This resolver should always -214 * call {@link CommandExecutionContext#popFirstArg()} -215 */ -216 public <T> void registerContext(Class<T> context, ContextResolver<T, R> supplier) { -217 contextMap.put(context, supplier); -218 } -219 -220 public ContextResolver<?, R> getResolver(Class<?> type) { -221 Class<?> rootType = type; -222 do { -223 if (type == Object.class) { -224 break; -225 } -226 -227 final ContextResolver<?, R> resolver = contextMap.get(type); -228 if (resolver != null) { -229 return resolver; -230 } -231 } while ((type = type.getSuperclass()) != null); -232 -233 this.manager.log(LogLevel.ERROR, "Could not find context resolver", new IllegalStateException("No context resolver defined for " + rootType.getName())); -234 return null; -235 } -236} +171 Integer perPage = c.getFlagValue("perpage", (Integer) null); +172 if (perPage != null) { +173 commandHelp.setPerPage(perPage); +174 } +175 commandHelp.setSearch(search); +176 return commandHelp; +177 }); +178 } +179 +180 /** +181 * @deprecated Please switch to {@link #registerIssuerAwareContext(Class, IssuerAwareContextResolver)} +182 * as the core wants to use the platform agnostic term of "Issuer" instead of Sender +183 * @see #registerIssuerAwareContext(Class, IssuerAwareContextResolver) +184 */ +185 @Deprecated +186 public <T> void registerSenderAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { +187 contextMap.put(context, supplier); +188 } +189 +190 /** +191 * Registers a context resolver that may conditionally consume input, falling back to using the context of the +192 * issuer to potentially fulfill this context. +193 * You may call {@link CommandExecutionContext#getFirstArg()} and then conditionally call {@link CommandExecutionContext#popFirstArg()} +194 * if you want to consume that input. +195 */ +196 public <T> void registerIssuerAwareContext(Class<T> context, IssuerAwareContextResolver<T, R> supplier) { +197 contextMap.put(context, supplier); +198 } +199 +200 /** +201 * Registers a context resolver that will never consume input. It will always satisfy its context based on the +202 * issuer of the command, so it will not appear in syntax strings. +203 */ +204 public <T> void registerIssuerOnlyContext(Class<T> context, IssuerOnlyContextResolver<T, R> supplier) { +205 contextMap.put(context, supplier); +206 } +207 +208 /** +209 * Registers a context that can safely accept a null input from the command issuer to resolve. This resolver should always +210 * call {@link CommandExecutionContext#popFirstArg()} +211 */ +212 public <T> void registerOptionalContext(Class<T> context, OptionalContextResolver<T, R> supplier) { +213 contextMap.put(context, supplier); +214 } +215 +216 /** +217 * Registers a context that requires input from the command issuer to resolve. This resolver should always +218 * call {@link CommandExecutionContext#popFirstArg()} +219 */ +220 public <T> void registerContext(Class<T> context, ContextResolver<T, R> supplier) { +221 contextMap.put(context, supplier); +222 } +223 +224 public ContextResolver<?, R> getResolver(Class<?> type) { +225 Class<?> rootType = type; +226 do { +227 if (type == Object.class) { +228 break; +229 } +230 +231 final ContextResolver<?, R> resolver = contextMap.get(type); +232 if (resolver != null) { +233 return resolver; +234 } +235 } while ((type = type.getSuperclass()) != null); +236 +237 this.manager.log(LogLevel.ERROR, "Could not find context resolver", new IllegalStateException("No context resolver defined for " + rootType.getName())); +238 return null; +239 } +240} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandHelp.html b/docs/acf-core/src-html/co/aikar/commands/CommandHelp.html index 122643b8..4f561264 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandHelp.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandHelp.html @@ -37,129 +37,163 @@ 029 030import java.util.*; 031import java.util.regex.Pattern; -032import java.util.stream.Stream; -033 -034@SuppressWarnings("WeakerAccess") -035public class CommandHelp { -036 private final CommandManager manager; -037 private final CommandIssuer issuer; -038 private final List<HelpEntry> helpEntries = new ArrayList<>(); -039 private int page; +032 +033@SuppressWarnings("WeakerAccess") +034public class CommandHelp { +035 private final CommandManager manager; +036 private final CommandIssuer issuer; +037 private final List<HelpEntry> helpEntries = new ArrayList<>(); +038 private int page; +039 private int perPage; 040 private List<String> search; 041 042 public CommandHelp(CommandManager manager, RootCommand rootCommand, CommandIssuer issuer) { 043 this.manager = manager; 044 this.issuer = issuer; -045 -046 SetMultimap<String, RegisteredCommand> subCommands = rootCommand.getSubCommands(); -047 Set<RegisteredCommand> seen = new HashSet<>(); -048 subCommands.entries().forEach(e -> { -049 String key = e.getKey(); -050 if (key.equals("__default") || key.equals("__unknown")){ -051 return; -052 } -053 -054 RegisteredCommand regCommand = e.getValue(); -055 if (regCommand.hasPermission(issuer) && !seen.contains(regCommand)) { -056 this.helpEntries.add(new HelpEntry(regCommand)); -057 seen.add(regCommand); -058 } -059 }); -060 } -061 -062 @UnstableAPI // Not sure on this one yet even when API becomes unstable -063 protected void updateSearchScore(HelpEntry help) { -064 if (this.search == null || this.search.isEmpty()) { -065 help.setSearchScore(1); -066 return; -067 } -068 final RegisteredCommand<?> cmd = help.getRegisteredCommand(); -069 -070 int searchScore = 0; -071 for (String word : this.search) { -072 Pattern pattern = Pattern.compile(".*" + Pattern.quote(word) + ".*", Pattern.CASE_INSENSITIVE); -073 for (String subCmd : cmd.registeredSubcommands) { -074 Pattern subCmdPattern = Pattern.compile(".*" + Pattern.quote(subCmd) + ".*", Pattern.CASE_INSENSITIVE); -075 if (pattern.matcher(subCmd).matches()) { -076 searchScore += 3; -077 } else if (subCmdPattern.matcher(word).matches()) { -078 searchScore++; -079 } -080 } -081 +045 this.perPage = manager.defaultHelpPerPage; +046 +047 SetMultimap<String, RegisteredCommand> subCommands = rootCommand.getSubCommands(); +048 Set<RegisteredCommand> seen = new HashSet<>(); +049 subCommands.entries().forEach(e -> { +050 String key = e.getKey(); +051 if (key.equals("__default") || key.equals("__unknown")){ +052 return; +053 } +054 +055 RegisteredCommand regCommand = e.getValue(); +056 if (regCommand.hasPermission(issuer) && !seen.contains(regCommand)) { +057 this.helpEntries.add(new HelpEntry(regCommand)); +058 seen.add(regCommand); +059 } +060 }); +061 } +062 +063 @UnstableAPI // Not sure on this one yet even when API becomes unstable +064 protected void updateSearchScore(HelpEntry help) { +065 if (this.search == null || this.search.isEmpty()) { +066 help.setSearchScore(1); +067 return; +068 } +069 final RegisteredCommand<?> cmd = help.getRegisteredCommand(); +070 +071 int searchScore = 0; +072 for (String word : this.search) { +073 Pattern pattern = Pattern.compile(".*" + Pattern.quote(word) + ".*", Pattern.CASE_INSENSITIVE); +074 for (String subCmd : cmd.registeredSubcommands) { +075 Pattern subCmdPattern = Pattern.compile(".*" + Pattern.quote(subCmd) + ".*", Pattern.CASE_INSENSITIVE); +076 if (pattern.matcher(subCmd).matches()) { +077 searchScore += 3; +078 } else if (subCmdPattern.matcher(word).matches()) { +079 searchScore++; +080 } +081 } 082 -083 if (pattern.matcher(help.getDescription()).matches()) { -084 searchScore += 2; -085 } -086 if (pattern.matcher(help.getParameterSyntax()).matches()) { -087 searchScore++; -088 } -089 if (help.getSearchTags() != null && pattern.matcher(help.getSearchTags()).matches()) { -090 searchScore += 2; -091 } -092 } -093 help.setSearchScore(searchScore); -094 } -095 -096 public CommandManager getManager() { -097 return manager; -098 } -099 -100 public void showHelp() { -101 showHelp(issuer, MessageKeys.HELP_FORMAT); -102 } -103 -104 public void showHelp(CommandIssuer issuer) { -105 showHelp(issuer, MessageKeys.HELP_FORMAT); -106 } -107 -108 public void showHelp(CommandIssuer issuer, MessageKeyProvider format) { -109 Iterator<HelpEntry> results = getHelpEntries().stream() -110 .filter(HelpEntry::shouldShow) -111 .sorted(Comparator.comparingInt(helpEntry -> helpEntry.getSearchScore() * -1)).iterator(); -112 if (!results.hasNext()) { -113 issuer.sendMessage(MessageType.ERROR, MessageKeys.NO_COMMAND_MATCHED_SEARCH, "{search}", ACFUtil.join(this.search, " ")); -114 results = getHelpEntries().iterator(); -115 } -116 -117 while (results.hasNext()) { -118 HelpEntry e = results.next(); -119 String formatted = this.manager.formatMessage(issuer, MessageType.HELP, format, getFormatReplacements(e)); -120 for (String msg : ACFPatterns.NEWLINE.split(formatted)) { -121 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); -122 } -123 } -124 } -125 -126 /** -127 * Override this to control replacements -128 * @param e -129 * @return -130 */ -131 @NotNull -132 public String[] getFormatReplacements(HelpEntry e) { -133 //{command} {parameters} {separator} {description} -134 return new String[] { -135 "{command}", e.getCommand(), -136 "{parameters}", e.getParameterSyntax(), -137 "{separator}", e.getDescription().isEmpty() ? "" : "-", -138 "{description}", e.getDescription() -139 }; -140 } -141 -142 public List<HelpEntry> getHelpEntries() { -143 return helpEntries; -144 } -145 -146 public void setPage(int page) { -147 this.page = page; -148 } -149 -150 public void setSearch(List<String> search) { -151 this.search = search; -152 getHelpEntries().forEach(this::updateSearchScore); -153 } -154} +083 +084 if (pattern.matcher(help.getDescription()).matches()) { +085 searchScore += 2; +086 } +087 if (pattern.matcher(help.getParameterSyntax()).matches()) { +088 searchScore++; +089 } +090 if (help.getSearchTags() != null && pattern.matcher(help.getSearchTags()).matches()) { +091 searchScore += 2; +092 } +093 } +094 help.setSearchScore(searchScore); +095 } +096 +097 public CommandManager getManager() { +098 return manager; +099 } +100 +101 public void showHelp() { +102 showHelp(issuer, MessageKeys.HELP_FORMAT); +103 } +104 +105 public void showHelp(CommandIssuer issuer) { +106 showHelp(issuer, MessageKeys.HELP_FORMAT); +107 } +108 +109 public void showHelp(CommandIssuer issuer, MessageKeyProvider format) { +110 List<HelpEntry> helpEntries = getHelpEntries(); +111 Iterator<HelpEntry> results = helpEntries.stream() +112 .filter(HelpEntry::shouldShow) +113 .sorted(Comparator.comparingInt(helpEntry -> helpEntry.getSearchScore() * -1)).iterator(); +114 if (!results.hasNext()) { +115 issuer.sendMessage(MessageType.ERROR, MessageKeys.NO_COMMAND_MATCHED_SEARCH, "{search}", ACFUtil.join(this.search, " ")); +116 helpEntries = getHelpEntries(); +117 results = helpEntries.iterator(); +118 } +119 int totalResults = helpEntries.size(); +120 int min = (this.page-1) * this.perPage; // TODO: per page configurable? +121 int max = min + this.perPage; +122 int i = 0; +123 if (min >= totalResults) { +124 issuer.sendMessage(MessageType.HELP, MessageKeys.HELP_NO_RESULTS); +125 return; +126 } +127 +128 while (results.hasNext()) { +129 HelpEntry e = results.next(); +130 if (i >= max) { +131 break; +132 } +133 if (i++ < min) { +134 continue; +135 } +136 +137 String formatted = this.manager.formatMessage(issuer, MessageType.HELP, format, getFormatReplacements(e)); +138 for (String msg : ACFPatterns.NEWLINE.split(formatted)) { +139 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); +140 } +141 } +142 if (min > 0 || results.hasNext()) { +143 issuer.sendMessage(MessageType.HELP, MessageKeys.HELP_PAGE_INFORMATION, +144 "{page}", "" + this.page, +145 "{totalpages}", ""+ (int)Math.ceil((float)totalResults / (float)this.perPage), +146 "{results}", "" + totalResults +147 ); +148 } +149 } +150 +151 /** +152 * Override this to control replacements +153 * @param e +154 * @return +155 */ +156 @NotNull +157 public String[] getFormatReplacements(HelpEntry e) { +158 //{command} {parameters} {separator} {description} +159 return new String[] { +160 "{command}", e.getCommand(), +161 "{parameters}", e.getParameterSyntax(), +162 "{separator}", e.getDescription().isEmpty() ? "" : "-", +163 "{description}", e.getDescription() +164 }; +165 } +166 +167 public List<HelpEntry> getHelpEntries() { +168 return helpEntries; +169 } +170 +171 public void setPerPage(int perPage) { +172 this.perPage = perPage; +173 } +174 +175 public void setPage(int page) { +176 this.page = page; +177 } +178 +179 public void setPage(int page, int perPage) { +180 this.setPage(page); +181 this.setPerPage(perPage); +182 } +183 +184 public void setSearch(List<String> search) { +185 this.search = search; +186 getHelpEntries().forEach(this::updateSearchScore); +187 } +188} diff --git a/docs/acf-core/src-html/co/aikar/commands/CommandManager.html b/docs/acf-core/src-html/co/aikar/commands/CommandManager.html index f630a68d..c772f138 100644 --- a/docs/acf-core/src-html/co/aikar/commands/CommandManager.html +++ b/docs/acf-core/src-html/co/aikar/commands/CommandManager.html @@ -60,255 +60,268 @@ 052 protected Set<Locale> supportedLanguages = Sets.newHashSet(Locales.ENGLISH, Locales.GERMAN, Locales.SPANISH, Locales.CZECH); 053 protected Map<MessageType, F> formatters = new IdentityHashMap<>(); 054 protected F defaultFormatter; -055 private Set<String> unstableAPIs = Sets.newHashSet(); -056 -057 public static CommandOperationContext getCurrentCommandOperationContext() { -058 return commandOperationContext.get().peek(); -059 } -060 -061 public static CommandIssuer getCurrentCommandIssuer() { -062 CommandOperationContext context = commandOperationContext.get().peek(); -063 return context != null ? context.getCommandIssuer() : null; -064 } -065 -066 public static CommandManager getCurrentCommandManager() { -067 CommandOperationContext context = commandOperationContext.get().peek(); -068 return context != null ? context.getCommandManager() : null; -069 } -070 -071 public F setFormat(MessageType type, F formatter) { -072 return formatters.put(type, formatter); -073 } -074 -075 public F getFormat(MessageType type) { -076 return formatters.getOrDefault(type, defaultFormatter); -077 } -078 -079 public void setFormat(MessageType type, FT... colors) { -080 F format = getFormat(type); -081 for (int i = 0; i < colors.length; i++) { -082 format.setColor(i, colors[i]); -083 } -084 } -085 -086 public void setFormat(MessageType type, int i, FT color) { -087 F format = getFormat(type); -088 format.setColor(i, color); -089 } -090 -091 public F getDefaultFormatter() { -092 return defaultFormatter; -093 } -094 -095 public void setDefaultFormatter(F defaultFormatter) { -096 this.defaultFormatter = defaultFormatter; -097 } -098 -099 /** -100 * Gets the command contexts manager -101 * @return Command Contexts -102 */ -103 public abstract CommandContexts<?> getCommandContexts(); -104 -105 /** -106 * Gets the command completions manager -107 * @return Command Completions -108 */ -109 public abstract CommandCompletions<?> getCommandCompletions(); -110 -111 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -112 public CommandHelp generateCommandHelp(@NotNull String command) { -113 verifyUnstableAPI("help"); -114 CommandOperationContext context = getCurrentCommandOperationContext(); -115 if (context == null) { -116 throw new IllegalStateException("This method can only be called as part of a command execution."); -117 } -118 return generateCommandHelp(context.getCommandIssuer(), command); -119 } -120 -121 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -122 public CommandHelp generateCommandHelp(CommandIssuer issuer, @NotNull String command) { -123 verifyUnstableAPI("help"); -124 return generateCommandHelp(issuer, obtainRootCommand(ACFPatterns.SPACE.split(command, 2)[0])); -125 } -126 -127 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -128 public CommandHelp generateCommandHelp() { -129 verifyUnstableAPI("help"); -130 CommandOperationContext context = getCurrentCommandOperationContext(); -131 if (context == null) { -132 throw new IllegalStateException("This method can only be called as part of a command execution."); -133 } -134 String commandLabel = context.getCommandLabel(); -135 return generateCommandHelp(context.getCommandIssuer(), this.obtainRootCommand(commandLabel)); -136 } -137 -138 /** @deprecated Unstable API */ @Deprecated @UnstableAPI -139 public CommandHelp generateCommandHelp(CommandIssuer issuer, RootCommand rootCommand) { -140 verifyUnstableAPI("help"); -141 return new CommandHelp(this, rootCommand, issuer); -142 } -143 -144 /** -145 * Registers a command with ACF -146 * -147 * @param command The command to register -148 * @return boolean -149 */ -150 public abstract void registerCommand(BaseCommand command); -151 public abstract boolean hasRegisteredCommands(); -152 public abstract boolean isCommandIssuer(Class<?> type); -153 -154 // TODO: Change this to I if we make a breaking change -155 public abstract CommandIssuer getCommandIssuer(Object issuer); +055 protected int defaultHelpPerPage = 10; +056 private Set<String> unstableAPIs = Sets.newHashSet(); +057 +058 public static CommandOperationContext getCurrentCommandOperationContext() { +059 return commandOperationContext.get().peek(); +060 } +061 +062 public static CommandIssuer getCurrentCommandIssuer() { +063 CommandOperationContext context = commandOperationContext.get().peek(); +064 return context != null ? context.getCommandIssuer() : null; +065 } +066 +067 public static CommandManager getCurrentCommandManager() { +068 CommandOperationContext context = commandOperationContext.get().peek(); +069 return context != null ? context.getCommandManager() : null; +070 } +071 +072 public F setFormat(MessageType type, F formatter) { +073 return formatters.put(type, formatter); +074 } +075 +076 public F getFormat(MessageType type) { +077 return formatters.getOrDefault(type, defaultFormatter); +078 } +079 +080 public void setFormat(MessageType type, FT... colors) { +081 F format = getFormat(type); +082 for (int i = 0; i < colors.length; i++) { +083 format.setColor(i, colors[i]); +084 } +085 } +086 +087 public void setFormat(MessageType type, int i, FT color) { +088 F format = getFormat(type); +089 format.setColor(i, color); +090 } +091 +092 public F getDefaultFormatter() { +093 return defaultFormatter; +094 } +095 +096 public void setDefaultFormatter(F defaultFormatter) { +097 this.defaultFormatter = defaultFormatter; +098 } +099 +100 /** +101 * Gets the command contexts manager +102 * @return Command Contexts +103 */ +104 public abstract CommandContexts<?> getCommandContexts(); +105 +106 /** +107 * Gets the command completions manager +108 * @return Command Completions +109 */ +110 public abstract CommandCompletions<?> getCommandCompletions(); +111 +112 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +113 public CommandHelp generateCommandHelp(@NotNull String command) { +114 verifyUnstableAPI("help"); +115 CommandOperationContext context = getCurrentCommandOperationContext(); +116 if (context == null) { +117 throw new IllegalStateException("This method can only be called as part of a command execution."); +118 } +119 return generateCommandHelp(context.getCommandIssuer(), command); +120 } +121 +122 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +123 public CommandHelp generateCommandHelp(CommandIssuer issuer, @NotNull String command) { +124 verifyUnstableAPI("help"); +125 return generateCommandHelp(issuer, obtainRootCommand(ACFPatterns.SPACE.split(command, 2)[0])); +126 } +127 +128 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +129 public CommandHelp generateCommandHelp() { +130 verifyUnstableAPI("help"); +131 CommandOperationContext context = getCurrentCommandOperationContext(); +132 if (context == null) { +133 throw new IllegalStateException("This method can only be called as part of a command execution."); +134 } +135 String commandLabel = context.getCommandLabel(); +136 return generateCommandHelp(context.getCommandIssuer(), this.obtainRootCommand(commandLabel)); +137 } +138 +139 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +140 public CommandHelp generateCommandHelp(CommandIssuer issuer, RootCommand rootCommand) { +141 verifyUnstableAPI("help"); +142 return new CommandHelp(this, rootCommand, issuer); +143 } +144 +145 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +146 public int getDefaultHelpPerPage() { +147 verifyUnstableAPI("help"); +148 return defaultHelpPerPage; +149 } +150 +151 /** @deprecated Unstable API */ @Deprecated @UnstableAPI +152 public void setDefaultHelpPerPage(int defaultHelpPerPage) { +153 verifyUnstableAPI("help"); +154 this.defaultHelpPerPage = defaultHelpPerPage; +155 } 156 -157 public abstract RootCommand createRootCommand(String cmd); -158 -159 /** -160 * Returns a Locales Manager to add and modify language tables for your commands. -161 * @return +157 /** +158 * Registers a command with ACF +159 * +160 * @param command The command to register +161 * @return boolean 162 */ -163 public abstract Locales getLocales(); -164 -165 public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs); +163 public abstract void registerCommand(BaseCommand command); +164 public abstract boolean hasRegisteredCommands(); +165 public abstract boolean isCommandIssuer(Class<?> type); 166 -167 public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args); -168 -169 public abstract void log(final LogLevel level, final String message, final Throwable throwable); -170 -171 public void log(final LogLevel level, final String message) { -172 log(level, message, null); -173 } -174 -175 /** -176 * Lets you add custom string replacements that can be applied to annotation values, -177 * to reduce duplication/repetition of common values such as permission nodes and command prefixes. -178 * -179 * Any replacement registered starts with a % -180 * -181 * So for ex @CommandPermission("%staff") -182 * @return Replacements Manager -183 */ -184 public CommandReplacements getCommandReplacements() { -185 return replacements; +167 // TODO: Change this to I if we make a breaking change +168 public abstract CommandIssuer getCommandIssuer(Object issuer); +169 +170 public abstract RootCommand createRootCommand(String cmd); +171 +172 /** +173 * Returns a Locales Manager to add and modify language tables for your commands. +174 * @return +175 */ +176 public abstract Locales getLocales(); +177 +178 public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs); +179 +180 public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args); +181 +182 public abstract void log(final LogLevel level, final String message, final Throwable throwable); +183 +184 public void log(final LogLevel level, final String message) { +185 log(level, message, null); 186 } 187 -188 public boolean hasPermission(CommandIssuer issuer, String permission) { -189 return permission == null || permission.isEmpty() || issuer.hasPermission(permission); -190 } -191 -192 public synchronized RootCommand obtainRootCommand(String cmd) { -193 return rootCommands.computeIfAbsent(cmd.toLowerCase(), this::createRootCommand); -194 } -195 -196 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { -197 return new RegisteredCommand(command, cmdName, method, prefSubCommand); -198 } -199 -200 /** -201 * Sets the default {@link ExceptionHandler} that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered. -202 * -203 * @param exceptionHandler the handler that should handle uncaught exceptions -204 */ -205 public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler) { -206 defaultExceptionHandler = exceptionHandler; +188 /** +189 * Lets you add custom string replacements that can be applied to annotation values, +190 * to reduce duplication/repetition of common values such as permission nodes and command prefixes. +191 * +192 * Any replacement registered starts with a % +193 * +194 * So for ex @CommandPermission("%staff") +195 * @return Replacements Manager +196 */ +197 public CommandReplacements getCommandReplacements() { +198 return replacements; +199 } +200 +201 public boolean hasPermission(CommandIssuer issuer, String permission) { +202 return permission == null || permission.isEmpty() || issuer.hasPermission(permission); +203 } +204 +205 public synchronized RootCommand obtainRootCommand(String cmd) { +206 return rootCommands.computeIfAbsent(cmd.toLowerCase(), this::createRootCommand); 207 } 208 -209 /** -210 * Gets the current default exception handler, might be null. -211 * -212 * @return the default exception handler -213 */ -214 public ExceptionHandler getDefaultExceptionHandler() { -215 return defaultExceptionHandler; -216 } -217 -218 protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, CommandIssuer sender, List<String> args, Throwable t) { -219 boolean result = false; -220 if (scope.getExceptionHandler() != null) { -221 result = scope.getExceptionHandler().execute(scope, registeredCommand, sender, args, t); -222 } else if (defaultExceptionHandler != null) { -223 result = defaultExceptionHandler.execute(scope, registeredCommand, sender, args, t); -224 } -225 return result; -226 } -227 -228 public void sendMessage(I issuerArg, MessageType type, MessageKeyProvider key, String... replacements) { -229 sendMessage(getCommandIssuer(issuerArg), type, key, replacements); -230 } -231 -232 public void sendMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { -233 String message = formatMessage(issuer, type, key, replacements); -234 -235 for (String msg : ACFPatterns.NEWLINE.split(message)) { -236 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); +209 public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { +210 return new RegisteredCommand(command, cmdName, method, prefSubCommand); +211 } +212 +213 /** +214 * Sets the default {@link ExceptionHandler} that is called when an exception occurs while executing a command, if the command doesn't have it's own exception handler registered. +215 * +216 * @param exceptionHandler the handler that should handle uncaught exceptions +217 */ +218 public void setDefaultExceptionHandler(ExceptionHandler exceptionHandler) { +219 defaultExceptionHandler = exceptionHandler; +220 } +221 +222 /** +223 * Gets the current default exception handler, might be null. +224 * +225 * @return the default exception handler +226 */ +227 public ExceptionHandler getDefaultExceptionHandler() { +228 return defaultExceptionHandler; +229 } +230 +231 protected boolean handleUncaughtException(BaseCommand scope, RegisteredCommand registeredCommand, CommandIssuer sender, List<String> args, Throwable t) { +232 boolean result = false; +233 if (scope.getExceptionHandler() != null) { +234 result = scope.getExceptionHandler().execute(scope, registeredCommand, sender, args, t); +235 } else if (defaultExceptionHandler != null) { +236 result = defaultExceptionHandler.execute(scope, registeredCommand, sender, args, t); 237 } -238 } -239 -240 public String formatMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { -241 String message = getLocales().getMessage(issuer, key.getMessageKey()); -242 if (replacements.length > 0) { -243 message = ACFUtil.replaceStrings(message, replacements); -244 } -245 -246 message = getCommandReplacements().replace(message); +238 return result; +239 } +240 +241 public void sendMessage(I issuerArg, MessageType type, MessageKeyProvider key, String... replacements) { +242 sendMessage(getCommandIssuer(issuerArg), type, key, replacements); +243 } +244 +245 public void sendMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { +246 String message = formatMessage(issuer, type, key, replacements); 247 -248 MessageFormatter formatter = formatters.getOrDefault(type, defaultFormatter); -249 if (formatter != null) { -250 message = formatter.format(message); -251 } -252 return message; -253 } -254 -255 public Locale getIssuerLocale(CommandIssuer issuer) { -256 return getLocales().getDefaultLocale(); -257 } +248 for (String msg : ACFPatterns.NEWLINE.split(message)) { +249 issuer.sendMessageInternal(ACFUtil.rtrim(msg)); +250 } +251 } +252 +253 public String formatMessage(CommandIssuer issuer, MessageType type, MessageKeyProvider key, String... replacements) { +254 String message = getLocales().getMessage(issuer, key.getMessageKey()); +255 if (replacements.length > 0) { +256 message = ACFUtil.replaceStrings(message, replacements); +257 } 258 -259 -260 public CommandOperationContext createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args) { -261 return new CommandOperationContext( -262 this, -263 issuer, -264 command, -265 commandLabel, -266 args -267 ); -268 } -269 -270 /** -271 * Gets a list of all currently supported languages for this manager. -272 * These locales will be automatically loaded from -273 * @return -274 */ -275 public Set<Locale> getSupportedLanguages() { -276 return supportedLanguages; -277 } -278 -279 /** -280 * Adds a new locale to the list of automatic Locales to load Message Bundles for. -281 * All bundles loaded under the previous supported languages will now automatically load for this new locale too. -282 * -283 * @param locale -284 */ -285 public void addSupportedLanguage(Locale locale) { -286 supportedLanguages.add(locale); -287 getLocales().loadMissingBundles(); -288 } -289 -290 /** -291 * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF -292 * may require you to update your implementation to those unstable API's -293 */ -294 @Deprecated -295 public void enableUnstableAPI(String api) { -296 unstableAPIs.add(api); -297 } -298 void verifyUnstableAPI(String api) { -299 if (!unstableAPIs.contains(api)) { -300 throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs"); -301 } -302 } -303} +259 message = getCommandReplacements().replace(message); +260 +261 MessageFormatter formatter = formatters.getOrDefault(type, defaultFormatter); +262 if (formatter != null) { +263 message = formatter.format(message); +264 } +265 return message; +266 } +267 +268 public Locale getIssuerLocale(CommandIssuer issuer) { +269 return getLocales().getDefaultLocale(); +270 } +271 +272 +273 public CommandOperationContext createCommandOperationContext(BaseCommand command, CommandIssuer issuer, String commandLabel, String[] args) { +274 return new CommandOperationContext( +275 this, +276 issuer, +277 command, +278 commandLabel, +279 args +280 ); +281 } +282 +283 /** +284 * Gets a list of all currently supported languages for this manager. +285 * These locales will be automatically loaded from +286 * @return +287 */ +288 public Set<Locale> getSupportedLanguages() { +289 return supportedLanguages; +290 } +291 +292 /** +293 * Adds a new locale to the list of automatic Locales to load Message Bundles for. +294 * All bundles loaded under the previous supported languages will now automatically load for this new locale too. +295 * +296 * @param locale +297 */ +298 public void addSupportedLanguage(Locale locale) { +299 supportedLanguages.add(locale); +300 getLocales().loadMissingBundles(); +301 } +302 +303 /** +304 * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF +305 * may require you to update your implementation to those unstable API's +306 */ +307 @Deprecated +308 public void enableUnstableAPI(String api) { +309 unstableAPIs.add(api); +310 } +311 void verifyUnstableAPI(String api) { +312 if (!unstableAPIs.contains(api)) { +313 throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs"); +314 } +315 } +316} diff --git a/docs/acf-core/src-html/co/aikar/commands/MessageKeys.html b/docs/acf-core/src-html/co/aikar/commands/MessageKeys.html index 808154be..4d987662 100644 --- a/docs/acf-core/src-html/co/aikar/commands/MessageKeys.html +++ b/docs/acf-core/src-html/co/aikar/commands/MessageKeys.html @@ -53,13 +53,16 @@ 045 NOT_ALLOWED_ON_CONSOLE, 046 COULD_NOT_FIND_PLAYER, 047 HELP_FORMAT, -048 NO_COMMAND_MATCHED_SEARCH; -049 -050 private final MessageKey key = MessageKey.of("acf-core." + this.name().toLowerCase()); -051 public MessageKey getMessageKey() { -052 return key; -053 } -054} +048 NO_COMMAND_MATCHED_SEARCH, +049 HELP_PAGE_INFORMATION, +050 HELP_NO_RESULTS +051 ; +052 +053 private final MessageKey key = MessageKey.of("acf-core." + this.name().toLowerCase()); +054 public MessageKey getMessageKey() { +055 return key; +056 } +057} diff --git a/docs/acf-paper/co/aikar/commands/PaperCommandManager.html b/docs/acf-paper/co/aikar/commands/PaperCommandManager.html index c08b9b11..753f53e2 100644 --- a/docs/acf-paper/co/aikar/commands/PaperCommandManager.html +++ b/docs/acf-paper/co/aikar/commands/PaperCommandManager.html @@ -144,7 +144,7 @@ extends co.aikar.commands.BukkitCommandManager
  • Fields inherited from class co.aikar.commands.CommandManager

    -defaultExceptionHandler, defaultFormatter, formatters, replacements, rootCommands, supportedLanguages
  • +defaultExceptionHandler, defaultFormatter, defaultHelpPerPage, formatters, replacements, rootCommands, supportedLanguages
  • @@ -198,7 +198,7 @@ extends co.aikar.commands.BukkitCommandManager

    Methods inherited from class co.aikar.commands.CommandManager

    -addSupportedLanguage, createCommandOperationContext, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setFormat, setFormat, setFormat
  • +addSupportedLanguage, createCommandOperationContext, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getDefaultHelpPerPage, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setDefaultHelpPerPage, setFormat, setFormat, setFormat
  • @@ -276,7 +276,7 @@ extends co.aikar.commands.CommandManager<org.spongepowered.api.command.Comman

    Methods inherited from class co.aikar.commands.CommandManager

    -addSupportedLanguage, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setFormat, setFormat, setFormat
  • +addSupportedLanguage, enableUnstableAPI, formatMessage, generateCommandHelp, generateCommandHelp, generateCommandHelp, generateCommandHelp, getCommandReplacements, getCurrentCommandIssuer, getCurrentCommandManager, getCurrentCommandOperationContext, getDefaultExceptionHandler, getDefaultFormatter, getDefaultHelpPerPage, getFormat, getIssuerLocale, getSupportedLanguages, handleUncaughtException, hasPermission, log, obtainRootCommand, sendMessage, sendMessage, setDefaultExceptionHandler, setDefaultFormatter, setDefaultHelpPerPage, setFormat, setFormat, setFormat + + + + diff --git a/languages/core/acf-core_en.properties b/languages/core/acf-core_en.properties index 7fd2b2b0..e2dd48d8 100644 --- a/languages/core/acf-core_en.properties +++ b/languages/core/acf-core_en.properties @@ -28,10 +28,12 @@ acf-core.error_prefix = Error: {message} acf-core.error_performing_command = I'm sorry, but there was an error performing this command. acf-core.info_message = {message} acf-core.please_specify_one_of = Error: Please specify one of ({valid}). -acf-core.must_be_a_number = Error: Must be a number +acf-core.must_be_a_number = Error: Must be a number. acf-core.must_be_min_length = Error: Must be at least {min} characters long. acf-core.must_be_max_length = Error: Must be less than {max} characters long. acf-core.not_allowed_on_console = Error: Console may not execute this command. acf-core.could_not_find_player = Error: Could not find a player by the name: {search} acf-core.help_format = {command} {parameters} {separator} {description} acf-core.no_command_matched_search = No command matched {search}. +acf-core.help_page_information = - Showing page {page} of {totalpages} ({results} results). +acf-core.help_no_results = Error: No more results.