[Bug] argument parser cannot parse string with ":"
So while I was playing with this lib, I got it slowly working with a few commands except one.
I have tried every StringArgumentType (word and string) but it cannot read arguments with :
errors trown with toast123:toast456
word and string: throws: com.mojang.brigadier.exceptions.CommandSyntaxException: Expected whitespace to end one argument, but found trailing data at position 16: ...t toast123<--[HERE]
Note: I can't use greedyString since I use more arguments after this argument. It's late in the evening, may have overlooked something or I missed a class that I could use.
@DeStilleGast I don't think there's enough information here to help you effectively.
Can you post a code example of the command registration that you were attempting to parse, and the full command that you were entering?
As well as what you expected to happen, (clearly in this case, not throw errors) but it looks like this is only one small piece of the puzzle.
@ryantheleach yeah sure, makes sense
the code for the command is:
commandDispatcher.register(
literal("checkit")
.then(
argument("server", word())
.executes(c -> {
String server = c.getArgument("server", String.class);
int port = 25565;
if(server.contains(":")) {
String[] split = server.split(":");
server = split[0];
port = Integer.parseInt(split[1]);
}
checkWhitelisted(c.getSource(), server, port, c.getSource().getUsername());
return 1;
})
.then(argument("user", string())
.executes(c -> {
String server = c.getArgument("server", String.class);
int port = 25565;
if(server.contains(":")) {
String[] split = server.split(":");
server = split[0];
port = Integer.parseInt(split[1]);
}
checkWhitelisted(c.getSource(), server, port, c.getArgument("user", String.class));
return 1;
})))
);
and the command that I try to execute (command prefix removed): checkit 127.0.0.1:25566
what this command basicly should do is that is checks the database if a user is whitelisted or not (reply is done in the function itself)
current workaround is to use checkit "127.0.0.1:25566" but that can get annoying and confusing
The best solution here would be a custom argument so you can validate input quicker and do the splitting of port at parse-time instead of execute-time.
If you need to use string, you'll have to quote it. checkit "127.0.0.1:25566" - unquoted strings can only contain a limited set of characters.
@Dinnerbone I really don't need a string for it, I just parse a ip and port from a string with optional port option. I tried to make a custom argument, thought first it was going to be hard, but it is easier then it looks.
Created my own IpArgumentType and it works pretty.
My code for future people (it's maybe not pretty, but it works well): Class IpArgumentType
public class IpArgumentType implements ArgumentType<Ip> {
@Override
public <S> Ip parse(StringReader reader) throws CommandSyntaxException {
String input = reader.getRemaining().split(" ")[0];
reader.setCursor(reader.getCursor() + input.length());
return new Ip(input);
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return null;
}
@Override
public Collection<String> getExamples() {
return Arrays.asList("127.0.0.1", "127.0.0.1:25567");
}
}
Class Ip:
public class Ip {
private String ip;
private int port = 25565; //default port
public Ip(String ip) {
this.ip = ip;
if(ip.contains(":")) {
String[] split = ip.split(":");
this.ip = split[0];
try {
port = Integer.parseInt(split[1]);
}catch (NumberFormatException ex){
throw new NumberFormatException(String.format("%s is not a number !!", split[1]));
}
}
}
public Ip(String ip, int port) {
this.ip = ip;
this.port = port;
}
public String getIp() {
return ip;
}
public int getPort() {
return port;
}
}
but my issue is fixed, keep this bug open or can it be closed ?
This should be closed as 'not an issue' or the equivalent.
Technically it's not a bug because : is not part of the syntax for an unquoted string (though this is undocumented):
https://github.com/Mojang/brigadier/blob/cf754c4ef654160dca946889c11941634c5db3d5/src/main/java/com/mojang/brigadier/StringReader.java#L169-L175
The solution is (as was suggested) to create a custom argument that can parse values with : in them.