JorelAli / CommandAPI

A Bukkit/Spigot API for the command UI introduced in Minecraft 1.13

Home Page:https://commandapi.jorel.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

.withRequirement being called once you tab complete for arguments

ImNotStable opened this issue · comments

Description

I'd like CommandAPI to call the withRequirement lambda once you try to tab complete the first position ("test", "toggle", etc.)
I found out instead it calls the lambda several times once you join.
image

Expected code

  private final CommandTree command = new CommandTree("request")
    .then(new LiteralArgument("test")
      .executesPlayer((sender, args) -> {
        sender.sendMessage(Component.text(QualityEconomyAPI.hasRequest(sender.getUniqueId())));
      }))
    .then(new LiteralArgument("toggle")
      .executesPlayer(this::toggleRequests))
    .then(new MultiLiteralArgument("answer", "accept", "deny")
      .withRequirement(sender -> {
        if (sender instanceof Player) sender.sendMessage(Component.text("GOOD"));
        else sender.sendMessage(Component.text("BAD"));
        return (sender instanceof Player player) && QualityEconomyAPI.hasRequest(player.getUniqueId());
      })
      .then(new PlayerArgument("target")
        .replaceSuggestions(ArgumentSuggestions.strings(info -> {
          if (info.sender() instanceof Player player && requests.containsKey(player.getUniqueId()))
            return requests.get(player.getUniqueId()).keySet().stream().map(Bukkit::getOfflinePlayer).map(OfflinePlayer::getName).toArray(String[]::new);
          return new String[0];
        }))
        .executesPlayer(this::answerRequest)))
    .then(new LiteralArgument("send")
      .then(new PlayerArgument("target")
        .replaceSuggestions(CommandUtils.getOnlinePlayerSuggestion())
        .then(new DoubleArgument("amount", Number.getMinimumValue())
          .executesPlayer(this::request))));

Extra details

No response

This sounds like it is working as intended. In vanilla, the client never asks the server which commands it can access. Instead, when the player joins, the server will figure out which commands they can access based on the requirements. This means that the server only needs to tell the client about the commands that they can access, so less information needs to be sent over the network.

If the requirements for your command change, you can trigger the server to resend commands to the player by calling Player#updateCommands or CommandAPI#updateRequirements. This is described in the documentation here: https://commandapi.jorel.dev/9.3.0/requirements.html#updating-requirements.

So how can I update the list of acceptable arguments when they tab complete the suggestions?

You probably want to call Player#updateCommands or CommandAPI#updateRequirements whenever the information being accessed by QualityEconomyAPI.hasRequest(player.getUniqueId()) (as seen in your code's call to withRequirement) changes.

I don't know how your system is structured, but from a quick look at your repo (which might be out of date compared to your current code), I think you would need to expand on these lines:

https://github.com/ImNotStable/QualityEconomy/blob/089471e192cb2cfa9beb81d8e33722dea598d325/src/main/java/com/imnotstable/qualityeconomy/commands/RequestCommand.java#L80-L81

requests.computeIfAbsent(requesteeUUID, uuid -> new HashMap<>()).put(requesterUUID, amount);
Bukkit.getScheduler().runTaskLater(QualityEconomy.getInstance(), () -> requests.get(requesteeUUID).remove(requesterUUID, amount), 1200);

To properly update the requestee client on whether or not they are able to access the answer, accept, and deny multiliteral, you can do something like this:

requests.computeIfAbsent(requesteeUUID, uuid -> new HashMap<>()).put(requesterUUID, amount);
CommandAPI.updateRequirements(requestee);

Bukkit.getScheduler().runTaskLater(QualityEconomy.getInstance(), () -> {
    requests.get(requesteeUUID).remove(requesterUUID, amount);
    CommandAPI.updateRequirements(requestee);
}, 1200);

Whenever a player gains or loses a request, the result returned by QualityEconomyAPI#hasRequest in the call to withRequirement might change, so you should call CommandAPI#updateRequriements or Player#updateCommands to reevaluate the requirements.

Thank you for the help!