JorelAli / CommandAPI

A Bukkit/Spigot API for the command UI introduced in Minecraft 1.13
https://commandapi.jorel.dev
MIT License
504 stars 60 forks source link

Better help and usage #562

Open 0x000006 opened 1 month ago

0x000006 commented 1 month ago

Description

A command may have branches that only operators can access or it may only be executed by a player which may lead to some confusion if the help and usage is the same for everyone.

My solution for that is a different help and usage message for different command executors and a help supplier. For example an ender chest command may open other players' ender chests if the executor is an operator but normally it would only open the executor's ender chest, or a command that can only be executed by a player may have a help message that indicates exactly that but if a player runs the help command it would display another help message.

The generic help messages and methods that everyone sees would stay the same but you could "override" them with some new methods. For example .withFullDescriptionPlayerSupplier(Function<Player, String>) or .withHelpPlayerSupplier(Function<Player, Pair<String, String>>) or .withHelpPlayerSupplier(Function<Player, HelpTopic>) and so on...

The usage message could get some new methods too: .addUsage(String... usage) or .addUsageSupplier(Supplier<String[]>) or .addUsageCollectionSupplier(Supplier<Collection<String>>) or .addUsagePlayerSupplier(Function<Player, String[]>) and so on...

There would be lots of help methods but I think it's worth it in the end.

Expected code

new CommandTree("enderchest")
    .withShortDescription("Opens your Ender Chest")
    .withShortDescriptionConsole("Only players can execute this")
    .withShortDescriptionPlayerSupplier(helpee -> helpee.isOp() ? "Opens players' Ender Chests" : "Opens your Ender Chest")     
    .executesPlayer((sender, args) -> {
        sender.openInventory(sender.getEnderChest());
    })
    .then(new PlayerArgument("target")
        .executesPlayer((sender, args) -> {
            sender.openInventory(((Player) args.get("target")).getEnderChest());
        })
    )
    .register("exampleplugin");

Extra details

No response

JorelAli commented 1 month ago

For help available in the /help command, the CommandAPI offers support for providing a HelpTopic object associated with that command, which has much more control over the content being displayed depending on the current CommandSender. More information about this can be found in the CommandAPI Documentation for Advanced help topics.

0x000006 commented 1 month ago

Thanks for the quick response. A little problem with this method is that it takes up some space, that's why i made this too. Please take this idea into consideration because it's much simpler than the HelpTopic method. I'll be closing the issue for now.

willkroboth commented 1 month ago

There are actually some API methods like your suggestions currently in development on the dev/command-build-rewrite branch: https://github.com/JorelAli/CommandAPI/commit/dd12720e041df9cbc9cb9e7894bc883bdee65e76#diff-386a6a2c0503f5e11c068e5cb56ec609dac4d3f71f0d3aa10071b728f22a340bR231.

Using Bukkit’s help API, it is not possible to change the short description based on the CommandSender. However, the changes I linked do allow you to specify a generator for the full description and usage that takes the sender as input. I like that since the CommandAPI typically adds extra formatting that is not available by default when using Bukkit’s HelpTopic. I hadn’t considered methods like helpForConsole or helpForPlayers, but that is still possible by checking sender instanceof Player and so forth.

This issue is also related #470. The same commit on dev/command-build-rewrite resolves that issue, and makes it so senders can only see CommandAPI generated command help or branch usage if they meet command or argument permissions and requirements.

I’m reopening this issues for tracking for dev/command-build-rewrite :)