List of Item NBTTags used standard in CraftBukkit

Discussion in 'Plugin Development' started by mr.deek, Nov 27, 2012.

?

Should NBTags be forced to a type (String/Int/Hash)? (so they can be easly listed for future use?)

  1. Yes

    65.0%
  2. No

    35.0%
Thread Status:
Not open for further replies.
  1. Offline

    mr.deek

    This was a pain and could not find this information easily anywhere... #GoogleFail
    If i missed any let me know I'll try to keep this posed updated with current NBTag information.

    LINK: (More Good Info!) Thx @GoMoew
    http://www.minecraftwiki.net/wiki/Chunk_format


    Your plugins can add any tag they wish but this list is for standard NBTTags only.
    If any of the values are null, just means they have not been set yet.

    Version: CraftBukkit 1.4.5

    Syntax used:
    Compound = NBTTagCompound(); // Means there's a subset of tags;
    List = NBTTagList; // Means has a list of sub values;
    Str = String
    Int = Integer
    Short = Short

    Known NBTags:
    <Weapon/Tool>
    display:Compound
    Name:Str
    Lore:List
    setString("1", "Line1")​
    setString("1", "Line1")​
    ench:list (id:Short, level:Short(Byte))
    RepairCost:int // not used but is coded.

    <Armour>
    display:Compound
    Name:Str
    Color:Short(Byte 0xFFFFF)
    ench:list (id:Short, level:Short(Byte))
    RepairCost:int // not used but is coded.

    <Armour Heads>
    display:Compound
    Name:Str
    RepairCost:Int // not used but is coded.
    ExtraType:Str // Name of head.

    <equipment>
    ench:list(Int); Returns (id:Short, level:Short(Bite)) values
    RepairCost:int

    <Books>
    pages:List(Int); Returns (Str) Values
    author:Str
    title:Str



    Code:
    // Working example of reading and setting item hands' NBTTag content.
     
    @EventHandler
        private void PlayerInteractEvent(PlayerInteractEvent playerInteractEvent)
            {
            Player player = playerInteractEvent.getPlayer();  // set player to current player.
            ItemStack itemStack = playerInteractEvent.getItem(); // Set item stack to current players item in hand.
            CraftItemStack craftItemStack = ((CraftItemStack) itemStack); // set the item to craft bukkit format (allows for meta data access).
            NBTTagCompound tagCompound = craftItemStack.getHandle().tag; // get the root of the meta data tree...
     
            NBTTagCompound display = null;
     
            if (tagCompound == null) // if the object never had metadata before, start a new table...
                {
                    tagCompound = new NBTTagCompound();
                }
     
            if (!tagCompound.hasKey("display")) // if the display meta branch does not exisit creatie it.
                {
                    tagCompound.set("display", new NBTTagCompound());
                }
     
            display = tagCompound.getCompound("display");
     
     
            // Get various Object's meta data
            playerInteractEvent.getPlayer().sendMessage("color:" + display.get("color"));
            playerInteractEvent.getPlayer().sendMessage("Name:" + display.getString("Name"));
            playerInteractEvent.getPlayer().sendMessage("Lore:" + display.getList("Lore"));
            playerInteractEvent.getPlayer().sendMessage("title:" + tagCompound.getString("title"));
            playerInteractEvent.getPlayer().sendMessage("author:" + tagCompound.getString("author"));
            playerInteractEvent.getPlayer().sendMessage("pages:" + tagCompound.getList("pages"));
     
     
            // Set Object colour (Candian!)
            // Adds 'dyed' title to object (indicating colour)
            display.setInt("color", ColourFromByte(0xFFF)); // 0xRGB
     
            // Set Item Name
            // Setting 'Name' value obsoletes the skulls owner value.
            NBTTagString name = new NBTTagString("1", ChatColor.translateAlternateColorCodes('&', "&rName"));
            display.set("Name", name);
     
     
            // Set Skulls Owner (same as Name but in short format)
            // if 'Name' value above is set Skull Owner is ignored.
            tagCompound.set("SkullOwner", new NBTTagString("1", ChatColor.translateAlternateColorCodes('&', "&r" + player.getName())));
     
     
            //Set Lore Name
            NBTTagList lore = new NBTTagList();
            lore.add(new NBTTagString("1", ChatColor.translateAlternateColorCodes('&', "&rLor1"))); // add lines (line 1, ...) ...
            lore.add(new NBTTagString("2", ChatColor.translateAlternateColorCodes('&', "&rLor1")));
            lore.add(new NBTTagString("3", ChatColor.translateAlternateColorCodes('&', "&rLor3")));
            display.set("Lore", lore);
     
     
            // Assing the changed Meta back to the item.
            craftItemStack.getHandle().setTag(tagCompound);
     
     
            // Put the ItemStack back in the players hand.  // (May not be required?)
            playerInteractEvent.getPlayer().setItemInHand(craftItemStack);
     
            }
     
     
        private Integer ColourFromByte(int value)
            {
            Integer result;
            if ((result = Integer.valueOf(value)) == null)
                {
                    return 0;
                }
     
            return result;
            }
     
    
     
    TheTinySpider likes this.
  2. Offline

    kyran_

    All of them are listed here by category:
    http://www.minecraftwiki.net/wiki/Chunk_format

    Probably not that intuitive of a search string for people who didn't know NBT data is mostly stored in the chunk files. Hopefully someone finds it useful as I have.
     
  3. Offline

    gomeow

    Also, you can change the title yourself (thread tools)
     
  4. Offline

    mr.deek

    kyran, I wish i had that link before I started this post :) that's exactly the info hidden i was looking for. ( I have nbt edit that shows me exiting labels, but does not show labels that can normal exist. Thank you.

    gomeow, Yup worked. but can't change the poll description, o well.
     
  5. Offline

    kyran_

    Probably so you can't change it from "Do you like cake?" to "Do you like prison sex?" after everyone's voted
     
  6. Offline

    raGan.

    FIRST VOTE ! (also first absolutely useless post in here)
     
  7. Offline

    kyran_

    I'd vote if I understood the question... But there's already several types of NBT tags, int, float, String, etc. I don't get what you mean really.
     
  8. Offline

    Jogy34

    Those are only entity/tile entity NBTTags and I think a few other things that are stored in chunk data. For player data and item data look here:
    http://www.minecraftwiki.net/wiki/Player.dat_Format


    And I am also confused. Is there a question here or are you just trying to compile a list of NBTTag stuff
     
  9. Offline

    kyran_

    Right, the player inventory and player tags are in each player's dat file. It explains it all in the entities section. I think in singleplayer the player is stored in the level dat files instead with everything else, but that's irrelevant I suppose considering the forum we're on...
     
  10. Offline

    Jogy34

    The RepairCost tags are used. They dictate how many levels to add when trying to repair/rename the specific item.

    As a side not, this is no offence intended to you, but I don't think you should be trying to compile a list of NBTTag stuff when:
    A) it doesn't look like you have much experiance with it and
    B) There are already lists out there that fully explain the NBTTag Structures and their uses on the minecraft forums.
     
  11. Offline

    mr.deek

    @ Jogy, ... this is my list with Example code ... if this article doesn't apply to you to don't both replying, it's here to help others.

    Yes, this is only for player item data (ItemStacks and Inventory). As I'm working on serializing all the objects to cross server game play development.

    @NOOBS yes this document will help you get started with NBTTags, use the link in the top for a full reference of all the Tags ...

    Everyone, if Bukkit or CraftBukkit actual finished the 'serialization' functions for object of item stack and inventory stack all of this is really pointless. I wouldn't even need to use NBTtags as objects in my project. I started this to document and create useful reference code for all noobs and expert programmers not familiar with the horrible code written before them. I hope this actually helps new developments from people then YAAA.

    kyran Ya but no one has Voted, so it silly :) but understood ...

    The reason i asked for the vote:

    As a plugin developer it would be nice to share NBT tags with other plugins rather then duplicating the values. If you say didn't know another plugin was going to already set an 'Bonus' Tag ... or something like that.

    I hate wasting bytes on duplicated information :)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  12. Offline

    kyran_

    But the nbt tags do have a specific type and you can check them before setting them. So if an object already had a Bonus tag that you didn't set, it could default to a different name to avoid conflicts.
     
  13. Offline

    coldandtired

    I'm pretty sure you can't add custom tags without handling the (de)serialization yourself. In which case you might as well store them however you want.
     
  14. Offline

    kyran_

    I'd imagine it just serializes the root compound and its contents along with it. You could have a custom tag to store data if you polled it later on when needed. But yeah if you're trying to make the tag actually effect the mob when it's loaded, it'd be a bit rough. I think you'd have to iterate over the entities, read the tags, and then do whatever action/modification that's required.
     
  15. Offline

    coldandtired

    Sadly, no.

    Calling the b() method will populate a compound with values from within the class (position, health, equipment, etc.)

    Calling the a()/d()/e() etc. methods will take the compound and extract all the information and add it to the class, but only the values it's expecting.
     
  16. Offline

    mr.deek

    kyran & @ ColdandTird,

    Yes to both.

    The problem with checking first is what happens if you wrote the value ( as it was unused ) then how would you know if another plugin used it after ( if it was poorly written not to check?

    Yes, I'm taking plan B. Serializing the object ( by manually looking up the NBTags and exporting them to JSON ). Then storing them in a 'sqlite' db. but i'm considering dropping the DB and just keep the info in another tag. ( I'm allowing players to have 2 inventory, one normal, and one by accessing /commmand

    I plan to publish the 1.4.5 R03 'itemstack' and 'inventory' serializing code when I'm done ...
     
  17. Offline

    kyran_

    Right, I was saying you'd have to read the tags yourself and perform and action based on what they contain. The minecraft classes are coded to discard any tags they don't recognize.

    I'm interested to see how people use the NBT tags for custom purposes though. I'm finishing up my Bukkit NBT editor plugin and there's some configurations that are never used by native code but might be useful to other plugin devs. Things like putting a list within a list, while odd, may be useful to someone else using the tags to store information.
     
  18. Offline

    coldandtired

    I can't see a use for them at all.

    If the data isn't stored on the mob/item/etc. itself, and needs to be serialized by each plugin why use it? Metadata is much more useful or a simple lookup table.
     
  19. Offline

    Jogy34

    The data is stored in the minecraft ItemStack itself for items and for mobs and TileEntities(which you can't even use metadata with) it is stored in the chunk data. Also it doesn't need to be serialized as minecraft keeps track of all of the NBTTags even after a server restart/reload.
     
  20. Offline

    coldandtired

    For standard tags, yes, but not custom ones as far as I can tell.
     
  21. Offline

    kyran_

    Hmm you seem to be right. I just used my nbteditor to add in a "Pork" int tag to a pig, restarted the server, opened the pig's tags back up and the tag's nowhere to be found. In that case it does seem like metadata is the better option.
     
  22. Offline

    coldandtired

    It doesn't even get saved to the mob.

    NBTTagCompound c = new NBTTagCompound();
    mob.b(c);
    c.setInt("test", 100);
    mob.a(c);

    // 'test' won't be here.
    mob.b(c);
     
  23. Offline

    mr.deek

    Well this should give someone a good start at reading and setting tags...

    HTML:
    package Mr.Deek.mCommon.Simplicity;
     
    import Mr.Deek.mCommon.mCommon;
    import net.minecraft.server.NBTTagByte;
    import net.minecraft.server.NBTTagCompound;
    import net.minecraft.server.NBTTagList;
    import net.minecraft.server.NBTTagString;
    import org.bukkit.ChatColor;
    import org.bukkit.Server;
    import org.bukkit.craftbukkit.inventory.CraftItemStack;
    import org.bukkit.inventory.ItemStack;
     
    import java.util.HashMap;
    import java.util.HashSet;
     
    /**
    * Created with IntelliJ IDEA.
    * User: Mr.Deek
    * Date: 28/11/12
    * Time: 2:26 PM
    * To change this template use File | Settings | File Templates.
    */
    public class SimpleItemStack {
     
    private mCommon mCommon;
    private Server server;
    private CraftItemStack simpleStack;
    private NBTTagCompound tagCompound;
     
    public SimpleItemStack(mCommon plugin, ItemStack itemStack)
    {
    mCommon = plugin;
    server = plugin.getServer();
    simpleStack = (CraftItemStack) itemStack;
    tagCompound = simpleStack.getHandle().getTag();
    }
     
    public NBTTagCompound getTagCompound()
    {
    return tagCompound;
    }
     
    // All ItemStacks
    public void SetName(String name) // null == remove
    {
    if (name == null) return;
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    NBTTagString value = new NBTTagString("1", ChatColor.translateAlternateColorCodes('&', "&r" + name));
    display.set("Name", value);
    tagCompound.set("display", display);
    _SetNBTTags();
    }
     
    //
    public String GetName() //
    {
    String result = "";
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    String Name = display.getString("Name");
    if (Name != null) result = Name;
    return result;
    }
     
    // All ItemStacks
    public void SetLore(HashSet<String> lore) // null == remove
    {
    if (lore == null) return;
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    NBTTagList value = new NBTTagList();
    for (String s : lore)
    {
    value.add(new NBTTagString("", ChatColor.translateAlternateColorCodes('&', "&r" + s)));
    }
    display.set("Lore", value);
    tagCompound.set("display", display);
    _SetNBTTags();
    }
     
    //
    public HashSet<String> GetLore() //
    {
    HashSet<String> result = new HashSet<String>();
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    NBTTagList value = display.getList("Lore");
    for (Integer i = 0; i < value.size(); i++)
    {
    result.add(value.get(i).toString());
    }
    return result;
    }
     
    public void AddLore(String lore)
    {
    if (lore == null) return;
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    NBTTagList value = display.getList("Lore");
    value.add(new NBTTagString("", ChatColor.translateAlternateColorCodes('&', "&r" + lore)));
    display.set("Lore", value);
    tagCompound.set("display", display);
    _SetNBTTags();
    }
     
    public void RemoveLore()
    {
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    display.remove("Lore");
    _SetNBTTags();
    }
     
    // Weapons and armour
    public HashMap<Short, Short> GetEnchantments()
    {
    HashMap<Short, Short> result = new HashMap<Short, Short>();
    NBTTagList listOfEnchantments = tagCompound.getList("ench");
     
    for (Integer i = 0; i < listOfEnchantments.size(); i++)
    {
    NBTTagCompound thisEnchantment = (NBTTagCompound) listOfEnchantments.get(i);
    short id = thisEnchantment.getShort("id");
    short lvl = thisEnchantment.getShort("lvl");
    result.put(id, lvl);
    }
     
    return result;
    }
     
    //
    public Short HasEnchantment(Short enchantmentID)//
    {
    if (enchantmentID == null) return 0;
    NBTTagList listOfEnchantments = tagCompound.getList("ench");
    if (listOfEnchantments == null) return 0;
    for (Short i = 0; i < listOfEnchantments.size(); i++)
    {
    NBTTagCompound thisEnchantment = (NBTTagCompound) listOfEnchantments.get(i);
     
    short id = thisEnchantment.getShort("id");
    if (id == enchantmentID) return i;
    }
    return 0;
    }
     
    //
    public void AddEnchantment(Short enchantmentID, Short enchantmentPower)//
    {
    if (enchantmentID == null || enchantmentPower == null) return;
    NBTTagList listOfEnchantments = tagCompound.getList("ench");
    Short enchPos;
     
    if ((enchPos = HasEnchantment(enchantmentID)) > 0) // enchantment already exists, replace it...
    {
    NBTTagCompound thisEnchantment = (NBTTagCompound) listOfEnchantments.get(enchPos);
    thisEnchantment.setShort("id", enchantmentID);
    thisEnchantment.setShort("lvl", enchantmentPower);
    }
    else
    {
    NBTTagCompound thisEnchantment = new NBTTagCompound();
    thisEnchantment.setShort("id", enchantmentID);
    thisEnchantment.setShort("lvl", enchantmentPower);
    }
     
    tagCompound.set("ench", listOfEnchantments);
    _SetNBTTags();
    }
     
    //
    public void RemoveEnchantment()//
    {
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    display.remove("ench");
    _SetNBTTags();
    }
     
     
    // Dyed colour items
    public void setColour(Byte colour) // null == remove
    {
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    display.set("color", new NBTTagByte("", colour));
    tagCompound.set("display", display);
    _SetNBTTags();
    }
     
    // Dyed colour items
    public Byte getColour(Byte Colour) // null == remove
    {
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    return display.getByte("color");
    }
     
    // Skull/Heads owners Name
    public void setSkullOwner(String Owner) // null == remove
    {
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    display.set("SkullOwner", new NBTTagString(ChatColor.translateAlternateColorCodes('&', Owner)));
    tagCompound.set("display", display);
    _SetNBTTags();
    }
     
    //
    public String getSkullOwner() // null == remove
    {
    NBTTagCompound display = _GetAndSet(tagCompound, "display");
    return display.getString("name");
    }
     
     
    // Books ('author', 'title, 'pages' as list.)
    public void setBook(String title, String author, HashSet<String> pages) // null == remove
    {
     
    NBTTagString NBtitle = new NBTTagString("title", title);
    NBTTagString NBauthor = new NBTTagString("author", author);
     
    NBTTagList NBPages = new NBTTagList();
    for (String page : pages)
    {
    NBPages.add(new NBTTagString("", page));
    }
     
    tagCompound.set("title", NBtitle);
    tagCompound.set("author", NBauthor);
    tagCompound.set("pages", NBPages);
    _SetNBTTags();
    }
     
    //
    public String getBookAuthor()//
    {
    return tagCompound.getString("author");
    }
     
    //
    public String getBookTitle()//
    {
    return tagCompound.getString("title");
    }
     
    //
    public HashSet<String> getBookPages()//
    {
    HashSet<String> pages = new HashSet<String>();
    NBTTagList NBpages = tagCompound.getList("pages");
    for (Short i = 0; i < NBpages.size(); i++)
    {
    pages.add(NBpages.get(i).toString());
    }
     
    return pages;
    }
     
    //
    public ItemStack getItemStack() // null == remove
    {
    return simpleStack;
    }
     
     
    // PRIVATE ---------------------------------------------------------------
    //
    private void _SetNBTTags()
    {
    simpleStack.getHandle().setTag(tagCompound);
    }
     
    private NBTTagCompound _GetAndSet(NBTTagCompound tagBase, String seachBase)
    {
    if (!tagBase.hasKey(seachBase))
    {
    tagBase.set(seachBase, new NBTTagCompound());
    }
     
    return tagBase.getCompound(seachBase);
    }
     
    }
    
     
Thread Status:
Not open for further replies.

Share This Page