NBT-API

NBT-API

98.9k Downloads

Get NBT as Map of String to Object

Smudgge opened this issue ยท 3 comments

commented

I was looking through the new wiki for 1.21, and I could not find any way of converting the NBT to a map.

Before the update, I could get around this by using the getObject() method, but now this doesn't exist.
And looking through the options, they all seem to require the plugin to know what type the value is.

commented

getObject() is an internal method and returns the nms item stack object, not a Map. There never has been a method to get the nbt as a map, as that would require creating a full copy of the nbt, and not really help with working with it.

commented

Hey, thanks for responding.

Ahh, I didn't realise that.

However, it would still be nice if there was a method to get the NBT as a map.

What i'm doing is: saving and loading items from a configuration file. Ive made it an option to easily change an items NBT. Very handy.

For Example

item:
  material: PAPER
  name: "&f&lPaper"
  nbt:
    key: "value"
    key2: 123

Currently i'm having to use a work around, essentially:

for (String key : nbt.getKeys) {
    
    if (nbt.getType(key).equals(...String) {
        map.put(key, nbt.getString(key);
    }
}

Forgive any errors currently on a phone.

It does work, but would be nice if there was just a NBT.asMap(itemStack);

Furthermore, why is it hard coded to throw an error when getting the full nbt? Sorry if this is already explained in the documentation.

NBT.get(itemStack, nbt -> nbt);

If nether of these are viable, no worries. Thanks for all efforts keeping it updated :)

commented

Furthermore, why is it hard coded to throw an error when getting the full nbt? Sorry if this is already explained in the documentation.
NBT.get(itemStack, nbt -> nbt);

Because the nbt is only valid inside the context, outside of the context it would give wrong results and not update the item correctly. There are other methods to get a persistent readonly copy of the nbt.

And you already noticed the issue on why a map is not helpful. When I give you a Map<String, Object>, you still need to iterate all the keys to decide how to handle them(String/Boolean/Integer/UUID etc), especially since Object might be another Map<String, Object>(so a Tag inside the Tag). And then parsing it back from the config you run into the same issues(arguably worse).
My recommendation is to ditch all of that and just save the item in the config(NBT.itemStackToNBT(item).toString()), not trying to invent a new storage format. Your current format will not work for 1.20.5+, and once you rework it, updating old configs to load on 1.21 for example will be really tricky.