⌨️Overview

Bad name I know

JackFredLib: Extra Command Source Data adds an attachment Minecraft's used when running commands. This allows you to attach extra context to advanced commands that redirect back into itself in the same vein as the position, entity, level, etcetera, and do advanced things such as repeatable arguments.

For some examples, see Where Is It's command with repeatable criteria, or the test mod's example for holding multiple strings or ints.

Adding Extra Data

To start, you'll want to create a class to hold your data, attached to a CommandSourceStack:

private static class MutliArgData implements ExtraSourceData<MutliArgData> {
    private final List<Integer> ints = new ArrayList<>();
    private final List<String> strs = new ArrayList<>();

    public MutliArgData() {
    }

    public MutliArgData(MutliArgData other) {
        this.ints.addAll(other.ints);
        this.strs.addAll(other.strs);
    }

    @Override
    public MutliArgData copy() {
        return new MutliArgData(this);
    }
}

Then when registering your command, you'll need to use the methods in ESD in the redirect lambda:

private static final ExtraSourceData.Definition<MutliArgData> DEFINITION = new ExtraSourceData.Definition<>(
    ResourceLocation.fromNamespaceAndPath("jackfredlib-testmod", "repeated_args"),
    MutliArgData.class,
    MutliArgData::new
);

static void setup() {
    CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
        LiteralCommandNode<CommandSourceStack> root = dispatcher.register(literal("repeatableArgs"));
        dispatcher.register(literal("repeatableArgs").then(
                    literal("int").then(
                            argument("int", IntegerArgumentType.integer())
                                    // getting or creating our data class and adding a value to it
                                    .redirect(root, ctx -> ESD.withCustom(ctx, DEFINITION, multiArg ->
                                            multiArg.ints.add(ctx.getArgument("int", Integer.class))
                                    ))
                    )).then(
                    literal("str").then(
                            argument("str", StringArgumentType.word())
                                    .redirect(root, ctx -> ESD.withCustom(ctx, DEFINITION, multiArg ->
                                            multiArg.strs.add(ctx.getArgument("str", String.class))
                                    ))
                    )).then(
                            literal("go").executes(ctx -> {
                                // getting our data
                                MultiArgData data = ESD.getCustom(ctx, DEFINITION);
                                List<Integer> ints = data.ints;
                                List<String> strs = data.strs;
                                
                                // do whatever
                                
                                return 0;
                            })
                    )
        );
    });
}

Last updated