#Components from strings? (SOLVED)

7 messages · Page 1 of 1 (latest)

crimson ice
#

With NBT you could not only get a string from an itemstack, but you could use StringNBTReader to parse said string back into an itemstack's NBT.

With the ComponentMaps, you can certainly get a string from one, but is there nothing to parse the string back into a component?

This was useful for writing to JSON config itemstacks for a player to edit either in config or in game via commands.

In lieu of such a functionality being missing, is there anything recommended to go about such instead?

somber wyvern
#

you can parse the nbt with StringNBTReader like normal, then use the codec from component to decode nbt to component

#

use Codec#decode(NbtOps.INSTANCE, nbtElement) to decode

crimson ice
#

I see, so my ComponentMap is done with ComponentMap.CODEC.decode(NbtOps.INSTANCE, nbt).result().get().getFirst();

Still, StringNBTReader expects the regular styled NBT to open with a curly bracket. [STDERR]: com.mojang.brigadier.exceptions.CommandSyntaxException: Expected '{' at position 0: <--[HERE]

Before what would have been
"item": "minecraft:bread{Enchantments:[{id:\"knockback\",lvl:2}]}"
in a config is now
"item": "minecraft:bread[minecraft:enchantments={levels:{\"minecraft:knockback\":2}}]"

if (group.item.contains("[")) {
    NbtCompound nbt;
    ComponentMap component;
    try {
      nbt = StringNbtReader.parse(group.item.substring(index));
      component = ComponentMap.CODEC.decode(NbtOps.INSTANCE, nbt).result().get().getFirst();
      itemStack.applyComponentsFrom(component);
    } catch (CommandSyntaxException e) {
       e.printStackTrace();
    }
}

I am using the substring of what corresponds to the component map in the same manner that I was doing for plain NBT, just now with the decode intermixed, but if it errors out from the initial parse, then where would I go from here?

somber wyvern
#

if you want something like /give command then i guess you can just use ItemStackArgument directly to parse

crimson ice
#

Ah rad, that simplifies things a lot as well.
Gone from...

public static ItemStack createItemStack(Config.Group group) {
    int index;
    Item item;
    if (group.item.contains("{")) {
        index = group.item.indexOf("{");
        item = Registries.ITEM.get(new Identifier(group.item.substring(0, index)));
    } else {
        index = 0;
        item = Registries.ITEM.get(new Identifier(group.item));
    }
    ItemStack itemStack = new ItemStack(item, ThreadLocalRandom.current().nextInt(group.min, group.max + 1));
    if (group.item.contains("{")) {
        NbtCompound nbt;
        try {
            nbt = StringNbtReader.parse(group.item.substring(index));
            itemStack.setNbt(nbt);
        } catch (CommandSyntaxException e) {
            e.printStackTrace();
        }
    }
    return itemStack;
}

...to...

public static ItemStack createItemStack(Config.Group group) {
    try {
        return new ItemStackArgumentType(CommandManager.createRegistryAccess(BuiltinRegistries.createWrapperLookup())).parse(new StringReader(group.item)).createStack(ThreadLocalRandom.current().nextInt(group.min, group.max + 1), true);
    } catch (CommandSyntaxException e) {
        throw new RuntimeException(e);
    }
}

Thank you for the suggestion!

#

Components from strings? (SOLVED)