#with pleasure
1 messages · Page 1 of 1 (latest)
public LiteralArgumentBuilder<CommandSourceStack> get() {
var gearLiteral = this.literal("gear");
var gearIdArgument = this.argument("gearId", StringArgumentType.string());
var qualityIdArgument = this.argument("qualityId", StringArgumentType.string());
gearIdArgument.suggests((ctx,builder) -> {
for (var entry : GameSystem.system().registryOf(Gear.class)) {
builder.suggest(entry.id());
}
return builder.buildFuture();
});
qualityIdArgument.suggests((ctx,builder) -> {
for (var entry : GameSystem.system().registryOf(GearQuality.class)) {
builder.suggest(entry.id());
}
return builder.buildFuture();
});
gearIdArgument.executes(ctx -> {
var gearId = StringArgumentType.getString(ctx, "gearId");
var system = GameSystem.system();
var gear = system.registryOf(Gear.class).byId(gearId);
ItemStack gearStack = gear.createStack();
@Nullable
var player = (Player) ctx.getSource().getBukkitEntity();
Util.failIfNull(player);
player.getInventory().addItem(gearStack);
return Command.SINGLE_SUCCESS;
});
qualityIdArgument.executes(ctx -> {
var gearId = StringArgumentType.getString(ctx, "gearId");
var qualityId = StringArgumentType.getString(ctx, "qualityId");
var system = GameSystem.system();
var gear = system.registryOf(Gear.class).byId(gearId);
var quality = system.registryOf(GearQuality.class).byId(qualityId);
ItemStack gearStack = gear.createStack(quality);
@Nullable
var player = (Player) ctx.getSource().getBukkitEntity();
Util.failIfNull(player);
player.getInventory().addItem(gearStack);
return Command.SINGLE_SUCCESS;
});
gearIdArgument.then(qualityIdArgument);
gearLiteral.then(gearIdArgument);
return gearLiteral;
}
@split night
the command is
/gear <gearId> <qualityId>
as an example
Il try it
/gear <gearId> works
but /gear does not work
because it misses a Command callback or well, there's no gearLiteral.executes(...) code
also I should say, it is possible to write it much more nested
like
lit1.then(arg1.then(lit2.then(arg2.executes(...).suggests(...)).executes(...).suggests(...)).executes(...).suggests(...)).executes(...).suggests(...)
but its not readable at all imo
/lit1 <arg1> lit2 <arg2>
its brigadder? implmeention seem different
if I understand its
gearIdArgument.then(qualityIdArgument);
gearLiteral.then(gearIdArgument);
return gearLiteral;
.then add add "at the suit" a new arg
if I want to allow denie /gear <gearId> without second arg how to do?
If you want to handle /gear <gearId> u need:
gearLiteral.then(gearIdArgument);
gearIdArgument.executes(...);
so if I dont define execute for gear id
/gear <gearId> dont work
but /gear <gearId> <a> work (a have a defined executor)
yes
good to know
u forgot to call .executes(...)on gearId argument
precisely
its kind of like a tree just
where sub trees are not assumed unless u explicitly do so urself
do you have an example for that you said about arguments with strings?
multiple spaces
I can do one for u
just remember its similar to varargs in java
that is, only the last argument is ever realistically of variable length
dont lose your time, its a simple curiosity
var arg = RequiredArgumentBuilder.<CommandSourceStack,String>argument("vararg",StringArgumentType.greedy());
arg.executes(ctx -> {
var vararg = StringArgumentType.getString(ctx,"vararg").split(" ");
return 0;
});
@split night
its sure that it work?
yea iirc thats exactly how it works
for spigot case, (of that I know about) I think it dont do that and it just treat commands without brigadier so it get all args as a string and split space to get an array?
https://wiki.vg/Protocol#Chat_Command yes it seem to just be arg, brigaddier is an abstraction server side
command node
which is like, hence why they use brigadier
probably that we you define command by sending it to client you can precise arguments (to use brigaddier server side) or just define command base without using brigaddier with https://wiki.vg/Command_Data
its time to sleep 
thanks for your help
yep
well greedy still works
because the protocol supports it
Spigot use that you think? Or just dont care and just Split the string like I said?
idk tbh
there is 3 type root, literal and argument literal seem to be just a word
like set, give (for example /time set)
what are exactly root and argument for?
literal is just a word "sub command"
root is also literal
but like its at the root
and argument is an arg yk
input parsing
what do you mean in "at the root"?
yes
but like
ofc the first argument token, that is the one after the slash, cannot be an argument
its always a literal
if I understand
/give Conclube diamond
root is give Conclube is argument and diamond is literal argument?
depends
I mean it could be
give root
Conclube <player>argument
diamond <string>argument
ah yes diamond can be just argument
yea
a better exampole
/calcul 7 3
7 3 are just argument
yea
we define an argument literal if we want that the client know it
/luckperms root
user literal
<user> argument
parent literal
set literal
<parent> argument
I mean its basically like a sub command
ah yes I see
or like an argument but it only accepts one specific variation of inputs
there is no inherent difference between a string literal "user" and a string argument, that only takes "user" as input
besides it seems to me that spigot command completion event is not called when client try to complete literal argument because its already defined and the client dosent send packets about it (with default spigot command it probably just wait for one argument (who accept space like you said it yesterady)
another way of describing literals is w normal spigot CommandExecutor u'd do sth like
CommandExecutor executor = (sender, cmd, label, args) -> {
if ("literal".equals(args[n]) {
//do stmh if /command literal ...
}
return true;
};```
yep
when I mean there's no inherent difference I obviously just imply they can be seen as isomorphic
yes
anyway u could probably write a suggestion handler that makes a string argument feel like a "literal" from tab completion pov
another example (Its for default /time command)
as we can see when you /time set you cane choose day, noone, night, midnight or give an int (in this case is a non literal argument) if we change that for a string argument, it will make problems? if I do a /time set night server can't know if night is the literal arg night or just a non literal ?
LiteralCommandNode<?> timeCommand = LiteralArgumentBuilder.literal("time")
.then(LiteralArgumentBuilder.literal("set")
.then(LiteralArgumentBuilder.literal("day"))
.then(LiteralArgumentBuilder.literal("noon"))
.then(LiteralArgumentBuilder.literal("night"))
.then(LiteralArgumentBuilder.literal("midnight"))
.then(RequiredArgumentBuilder.argument("time", IntegerArgumentType.integer())))
.then(LiteralArgumentBuilder.literal("add")
.then(RequiredArgumentBuilder.argument("time", IntegerArgumentType.integer())))
.then(LiteralArgumentBuilder.literal("query")
.then(LiteralArgumentBuilder.literal("daytime"))
.then(LiteralArgumentBuilder.literal("gametime"))
.then(LiteralArgumentBuilder.literal("day"))
).build();
ugh its rly hard to read the nested calls
sure
a bit messy since .then(...) isnt associative, nor commutative
coding with is the best way to wast 1 hour by trying to find a stupide errror
lol yea
well anyway
.then(...) is mutating anyway
so u dont have to nest
also a lil tip is to import LiteralArgumentBuilder and RequiredArgumentBuilder statically
or have a static factory method that infers the types and makes it less verbose
like I did w my example
alr lmk ^^
skips the argument then?
I havent test with 2 same literal, it probably just occure an error or call these two like if you set 2 non literal arguments
yea idk
I am not sure to undersatnd
what is certain is that a really bad idea to do that and there is no utility
I mean its just rare to append both an required-arg and literal-arg
on an argument yk
like either its just the argument (or arguments)
or its a set of literals
I think its impossible to need these two (or you just have to add a non literal and add compeltion you want)
mye
well, the way minecraft designs their commands
they dont even need to worry about these quirks
the behavior is intuitive and deterministic
to their extent of usage
when you enter a command with no execution code
for example /give but you put args you will get a default error message in red like
/give (inred)<-here command error blabla, I am not sure, client know that the command is not executable and show the message itself or its server?
can u rephrase the question?
yes I don't find it very useful
it makes it a lot more complicated for not much
but i assume u mean when u pass an invalid argument input to the argument parser
eh i mean its verbose
but like, idk if u can do it better
given their needs
a tree structure is logical
just accept arg as string array like spigot does it
wont work
because minecraft cares about narration
and user friendliness
also async command handling is easier
w the way its done rn
when you /give without arg you will got a default error in red (because there is not .executor method on this arg (it wait others args after it)), client know that and show itself error message? or its server
at start of minecraft I think commands concept dont exist for client or server its just a chat who start with / and plugins get arguments as a string
yea quite possible lol
like discord bot before interaction
its just that like, they take disabilities seriously
lol ye
w narration, Ig like languages yk
and then also minors, and bad player behavior
I think that the concept of node is made to simplify the different possibilities (Ihv forget the name but I remember a lib to create simple commands
which looked like that
@command("blabla")
@subcommand("")
it use brigaddier
well its time to eat
cloud maybe
they have an annotation system