#with pleasure

1 messages · Page 1 of 1 (latest)

fleet elk
#

    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

split night
#

Il try it

fleet elk
#

/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>

split night
#

its brigadder? implmeention seem different

fleet elk
#

its brigadier

#

ofc its in my own eco system

#

but yes

split night
fleet elk
#

yep

#

it appends (not prepend or insertion but APPENDS) the argument/literal

split night
#

if I want to allow denie /gear <gearId> without second arg how to do?

fleet elk
#

If you want to handle /gear <gearId> u need:

gearLiteral.then(gearIdArgument);
gearIdArgument.executes(...);
split night
fleet elk
#

yes

split night
#

good to know

fleet elk
#

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

split night
#

do you have an example for that you said about arguments with strings?

#

multiple spaces

fleet elk
#

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

split night
fleet elk
#
var arg = RequiredArgumentBuilder.<CommandSourceStack,String>argument("vararg",StringArgumentType.greedy());
arg.executes(ctx -> {
  var vararg = StringArgumentType.getString(ctx,"vararg").split(" "); 

  return 0;
});
#

@split night

split night
#

its sure that it work?

fleet elk
#

yea iirc thats exactly how it works

split night
#

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?

fleet elk
#

i think so

#

idk how its implemented tbh

#

i mean I did know, but i forgot :c

split night
fleet elk
#

i mean

#

there are some packets for the command syntax tree structure

split night
#

command node

fleet elk
#

which is like, hence why they use brigadier

split night
#

its time to sleep tardigrade

#

thanks for your help

split night
fleet elk
#

idk tbh

split night
fleet elk
#

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

split night
fleet elk
#

first argument

#

the thing after the slash

split night
#

after the first argument is not a root?

#

you mean

fleet elk
#

yes

#

but like

#

ofc the first argument token, that is the one after the slash, cannot be an argument

#

its always a literal

split night
fleet elk
#

depends

#

I mean it could be
give root
Conclube <player>argument
diamond <string>argument

split night
#

ah yes diamond can be just argument

fleet elk
#

yea

split night
#

a better exampole

fleet elk
#

i think a better example is luckperms

#

/luckperms user <user> parent set <parent>

split night
#

/calcul 7 3

7 3 are just argument

fleet elk
#

yea

split night
#

we define an argument literal if we want that the client know it

fleet elk
#

I mean its basically like a sub command

split night
#

ah yes I see

fleet elk
#

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

split night
#

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)

fleet elk
#

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;
};```
fleet elk
#

when I mean there's no inherent difference I obviously just imply they can be seen as isomorphic

split night
#

yes

fleet elk
# fleet elk yep

anyway u could probably write a suggestion handler that makes a string argument feel like a "literal" from tab completion pov

split night
#

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();

fleet elk
#

ugh its rly hard to read the nested calls

split night
#

sure

fleet elk
#

a bit messy since .then(...) isnt associative, nor commutative

split night
fleet elk
#

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

split night
#

ah yes

#

Il try I am really curiouse to know

fleet elk
#

alr lmk ^^

split night
#

it just call the literal

fleet elk
#

skips the argument then?

split night
#

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

fleet elk
#

yea idk

split night
split night
fleet elk
#

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

split night
fleet elk
#

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

split night
#

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?

fleet elk
#

can u rephrase the question?

split night
fleet elk
#

but i assume u mean when u pass an invalid argument input to the argument parser

fleet elk
#

but like, idk if u can do it better

#

given their needs

#

a tree structure is logical

split night
#

just accept arg as string array like spigot does it

fleet elk
#

wont work

#

because minecraft cares about narration

#

and user friendliness

#

also async command handling is easier

#

w the way its done rn

split night
# fleet elk can u rephrase the question?

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

fleet elk
#

client iirc

#

its ofc parsed at server

#

but iirc client does prematurely "check" yk

split night
# fleet elk and user friendliness

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

fleet elk
#

yea quite possible lol

split night
#

like discord bot before interaction

fleet elk
#

its just that like, they take disabilities seriously

fleet elk
fleet elk
#

and then also minors, and bad player behavior

split night
#

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

fleet elk
#

they have an annotation system