-
-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add variable length parameter #275
Comments
This request confuses me. What are you trying to achieve that a Is this not the best option for your situation? new CommandAPICommand("test")
.withArguments(new GreedyStringArgument("names"))
.executes((sender, args) -> {
String names = (String) args[0];
String commaSeparatedNames = Strings.join(Arrays.asList(names.split(" ")), ',');
})
.register(); |
No.
|
@SNWCreations This isn't something that requires a new argument - all you would need is a suitable suggestion function for a new CommandAPICommand("hunter")
.withArguments(new GreedyStringArgument("names").replaceSuggestions(ArgumentSuggestions.strings(info -> {
String currentArg = info.currentArg();
// If we end with a space, we prompt for the next player name
if(currentArg.endsWith(" ")) {
Set<String> players = new HashSet<>();
for(Player player : Bukkit.getOnlinePlayers()) {
players.add(player.getName());
}
players.removeAll(Arrays.asList(currentArg.split(" ")));
// 'players' now contains a set of all players that are NOT in
// the current list that the user is typing. We want to return
// a list of the current argument + each player that isn't
// in the list (i.e. each player in 'players')
return players.stream().map(player -> currentArg + player).toArray(String[]::new);
} else {
// Auto-complete the current player that the user is typing
// Remove the last argument and turn it into a string as the base for suggestions
List<String> currentArgList = new ArrayList<>(Arrays.asList(currentArg.split(" ")));
currentArgList.remove(currentArgList.size() - 1);
String suggestionBase = currentArgList.isEmpty() ? "" : currentArgList.stream().collect(Collectors.joining(" ")) + " ";
return Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getName().startsWith(currentArg.split(" ")[currentArg.split(" ").length - 1]))
.map(playerName -> suggestionBase + playerName)
.toArray(String[]::new);
}
})))
.executes((sender, args) -> {
String[] names = ((String) args[0]).split(" ");
Player[] players = Bukkit.getOnlinePlayers().stream()
.filter(player -> Arrays.asList(names).contains(player))
.toArray(Player[]::new);
})
.register(); (Note: I've not tested this!) |
Thanks! I will test it soon. |
@JorelAli |
This revised version of the code seems to be working for me: new CommandAPICommand("hunter")
.withArguments(new GreedyStringArgument("names").replaceSuggestions(ArgumentSuggestions.strings(info -> {
String currentArg = info.currentArg();
// If we end with a space, we prompt for the next player name
if(currentArg.endsWith(" ")) {
Set<String> players = new HashSet<>();
for(Player player : Bukkit.getOnlinePlayers()) {
players.add(player.getName());
}
Arrays.asList(currentArg.split(" ")).forEach(players::remove);
// 'players' now contains a set of all players that are NOT in
// the current list that the user is typing. We want to return
// a list of the current argument + each player that isn't
// in the list (i.e. each player in 'players')
return players.stream().map(player -> currentArg + player).toArray(String[]::new);
} else {
// Auto-complete the current player that the user is typing
// Remove the last argument and turn it into a string as the base for suggestions
List<String> currentArgList = new ArrayList<>(Arrays.asList(currentArg.split(" ")));
String nameStart = currentArgList.remove(currentArgList.size() - 1);
String suggestionBase = currentArgList.isEmpty() ? "" : String.join(" ", currentArgList) + " ";
return Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getName().startsWith(nameStart))
.map(player -> suggestionBase + player.getName())
.toArray(String[]::new);
}
})))
.executes((sender, args) -> {
String[] names = ((String) args[0]).split(" ");
Player[] players = Bukkit.getOnlinePlayers().stream()
.filter(player -> Arrays.asList(names).contains(player.getName()))
.toArray(Player[]::new);
})
.register(); Revising the original suggestion, I think it would be useful if the CommandAPI had a way to do this more compactly. Maybe something like this: new CommandAPICommand("hunter")
.withArguments(new GreedyArgument<Player>("players", Bukkit::getOnlinePlayers, Player::getName))
.executes((sender, args) -> {
Collection<Player> result = (Collection<Player>) args[0];
})
.register(); This new GreedyArgument(String nodeName, Supplier<Collection<T>> choices, Function<T, String> forCommand) It takes in a function that supplies a collection of some type to choose from (in this case If the |
I think your suggestion is also good. Why I said the code is not working? |
@willkroboth I quite like this idea. What we're effectively trying to achieve is some form of "list argument". The CommandAPI's I can envision something along the lines of: new ListArgument<Player>("players", " ", Player::getName)
.replaceSafeSuggestions(SafeSuggestions.suggest(Bukkit::getOnlinePlayers)); Where the second parameter (in this example, |
Wow! I like this! I think this can replace my original suggestion. |
@SNWCreations Why are you still using Minecraft 1.16.5? The CommandAPI is currently written in Java 17 and Minecraft 1.16.5 does not support Java 17. Backporting this feature is not only a vulnerability risk due to better security features in Java 17 and more powerful and performant features that are not present in Java 16. Additionally, there are certain features in Minecraft 1.16.5 that cannot be backported easily and would require a great deal of development time on my behalf that I would rather dedicate to more interesting upcoming features. Also, this feature is effectively syntactic sugar - it's possible to do this by writing your own methods. |
The reason is easy to understand. I need compatibility. |
The revised version of @JorelAli 's code by @willkroboth works. But it can't work correctly in console. |
I would like to add a variable-length parameter that wraps all known parameters (except itself).
It is like GreedyStringArgument, but it is enchanced.
Please supply examples of the desired inputs and outputs
Example:
Input:
/test a
Output:
a
But if we use
/test a b c
, it will say "a,b,c"Or "/test 0 1 2", it will say "0,1,2"
Example for Developers:
The text was updated successfully, but these errors were encountered: