Commands and General Arguments logic

Hey everyone.
I’m quite new to creating commands with Sponge and am trying to make a simple exp command which goes "/exp <show|set|give> ".
What I am wanting is for the exp set and give arguments to have both the player argument and the amount argument while having the show argument just have the player argument. What I have so far is that the amount argument is optional for all 3 of the first arguments. I am unsure how to structure this is a way that works the way I would like it. Any help would be greatly appreciated :slight_smile:

Code so far:
CommandSpec expCommand = CommandSpec.builder().description(Text.of("Show/Give/Set Players EXP")).arguments( GenericArguments.choices(Text.of("option"), ImmutableMap .<String, String>builder() .put("show", "show") .put("set", "set") .put("give", "give").build()), GenericArguments.player(Text.of("player")), GenericArguments.optional(GenericArguments.choices(Text.of("level"), ImmutableMap.<String, String>builder() .put("amount", "amount") .put("L", "L<level>").build()))) .executor(new ExpCommand()).build(); Sponge.getCommandManager().register(sm, expCommand, "exp", "xp");

What you should consider doing is creating children commands for each of your sub executions. For example:

CommandSpec show = CommandSpec.builder().description(...).arguments(GenericArguments.player(Text.of("target"))).executor(...).permission(...).build();
CommandSpec set = CommandSpec.builder().description(...).arguments(GenericArguments.player(Text.of("target")), GenericArguments.integer(Text.of("amount")), GenericArguments.boolean(Text.of("level"))).executor(...).permission(...).build();
CommandSpec give = CommandSpec.builder().description(...).arguments(GenericArguments.player(Text.of("target")), GenericArguments.integer(Text.of("amount")), GenericArguments.boolean(Text.of("level"))).executor(...).permission(...).build();

CommandSpec exp = CommandSpec.builder().description(...).permission(...).executor(... default cmd executor).child(show, "show").child(set, "set").child(give, "give").build();
Sponge.getCommandManager().register(plugin, exp, "exp", "xp");

That way, Sponge can properly pass arguments the way you want it to, and you can separate the implementations into much simpler code blocks (in your show, you can just get the player argument and show xp, without having to see if it is in fact the show command).

In general, if your command is to have multiple functions, it is best to split it into child commands and let Sponge parse the arguments for you, so that you can handle the functions separately, rather than checking it with conditions.

I put in ...'s where you need to fill in your own information, such as descriptions and executors. If you need help with the executors, let me know :).

Hey thanks for your help however I still have a problem with the way you have told me.
When I type “/exp” it will give me the syntax “/exp give|set|show” which is good, however when I specify such as “/exp give” It will tell me I don’t have enough arguments but it will tell me the usage is “/exp give|set|show” it will not tell me the “give” arguments.

Unfortunately, that is an issue with the current Sponge command system. From what I know, @dualspiral is working on a much better version of the system which will fix this issue, but until that is released there is not much you can do about that without handling a lot of low level command stuff. If you put in the correct number of arguments, the command will still work, it is just the usage that is not quite rite.