Resource Single Class NBT Editor for items, mobs, and tile entities! [1.8-1.12]

Discussion in 'Spigot Plugin Development' started by BananaPuncher714, Aug 30, 2017.

  1. I read this post here while I was trying to figure out how to detect whether an item was custom and set/get values from it. Some code was provided but it was all in NMS. I have successfully made a reflection version which you can implement very easily into your plugins. Now the need for hidden lore is gone!! This now works with ANY version(Maybe except for 1.13 :p)! The updated version also supports complex NBT manipulation with ITEMS, TILES and ENTITIES!!! :D
    Here are two pictures of an item, one with an nbt tag, and one without. The only way to see the amount of NBT tag info is using debug mode, but if it is turned off, both items look exactly the same.
    No NBT:
    [​IMG]
    Yes NBT:
    [​IMG]
    The new version also supports more complex NBT editing! Shout out to @kowagatte for his excellent tutorial on how to manipulate NBT tags! Here is a quick demo on how to use the updated version:
    Code (Java):

    // Here we have an ordinary ItemStack
    ItemStack item = new ItemStack( Material.GOLD_SWORD );
     
    // What's this!?! UNBREAKABILITY?!?! GREAT!
    item = NBTEditor.setItemTag( item, ( byte ) 1, "Unbreakable" );
     
    item = NBTEditor.setItemTag( item, ( short ) 1, "ench", null, "id" );
    // We can even add enchants to this thing!
    // Here are the arguments explained:
    // '( short ) 1' - The data value to set; Be sure you cast it to the appropriate type!
    // '"ench"' - The TagList that contains all the enchantments of an item
    // 'null' - This specifies we want to create a new list element, as opposed to editing an existing one
    // 'id' - This specifies the tag we want to edit, namely, the id of the enchantment
     
    item = NBTEditor.setItemTag( item, ( short ) 20, "ench", 0, "lvl" );
    // Now, to edit it, we provide the same arguments, except we change the 'null' to a 0, to specify the 1st element
    // We also change 'id' to 'lvl' because we want to set the level of the enchantment
     
    // Here is a more thorough chunk of code to set the item to do 20 damage when in the mainhand
    item = NBTEditor.setItemTag( item, "generic.attackDamage", "AttributeModifiers", null, "AttributeName" );
    item = NBTEditor.setItemTag( item, "generic.attackDamage", "AttributeModifiers", 0, "Name" );
    item = NBTEditor.setItemTag( item, "mainhand", "AttributeModifiers", 0, "Slot" );
    item = NBTEditor.setItemTag( item, ( double ) 20, "AttributeModifiers", 0, "Amount" );
    item = NBTEditor.setItemTag( item, 0, "AttributeModifiers", 0, "Operation" );
    item = NBTEditor.setItemTag( item, ( long ) 894654, "AttributeModifiers", 0, "UUIDLeast" );
    item = NBTEditor.setItemTag( item, ( long ) 2872, "AttributeModifiers", 0, "UUIDMost" );
     
    // Gettings the values still works the same way
    Object value = NBTEditor.getItemTag( item, "AttributeModifiers", 0, "Amount" );
    // value = 20 for the 20 damage it does

    // You can also use NBTEditor.setEntityTag() and ItemUtil.getEntityTag()

    // If you find any of this confusing, remember! It's completely optional as this version still
    // supports setting and getting simple tags! The only difference is that the arguments are swapped
    item = NBTEditor.setItemTag( item, "HELLO THIS IS THE VALUE NOW!", "A message" );
     
    Object message = NBTEditor.getItemTag( item, "A message" );
    // message = "HELLO THIS IS THE VALUE NOW!"

    // You can now also get nested hashmaps that contain all the tags and lists by not providing any arguments when using getItemTag();
     
    You can find the Item NBT data structure here.
    And here is the updated NBTEditor class for you to use! Perfect for custom items!
    Unfortunately, the final version is too large to fit on this post. Get the newest version here.
    The new version supports the following( basically all the data types available when working with NBT ):
    • Strings
    • Ints
    • Longs
    • Floats
    • Shorts
    • Bytes
    • Byte arrays
    • Int arrays
    Feel free to message me if you need any help understanding how to use this resource :).
    If you encounter any errors or bugs, tell me so I can fix it as quickly as possible! If you would also like additional features added, tell me too so I can add them!;)
     
    #1 BananaPuncher714, Aug 30, 2017
    Last edited: Mar 31, 2018
    • Useful Useful x 4
    • Like Like x 2
    • Winner Winner x 1
  2. Nice! I'll have to try it out some time.
     
  3. Is this something that get's retained upon server restarts? Or do I have to make sure the plugin re-adds these tags every time? (Don't know too much about the tags).
     
  4. This is restart persistent:)
     
  5. Sounds nifty. Will try it out. :)
     
  6. Oh really? Since when does MC store custom NBT data?
     
  7. Reflection is expensive, you should cache all the fields and stuff, here is an example.
     
    • Agree Agree x 1
    • Informative Informative x 1
  8. Turn that short into an integer and for arrays, use Gson?
     
  9. MC does store custom NBT data in itemstack, it does not work on entities and block states
     
    • Informative Informative x 1
  10. You can use a NBTList if i'm not wrong.
     
  11. I would probably do something like that, if you want you can try adding the NBTTagList and such:). I just use this for specifying what items are custom and stuff like that.
    Wow I had no idea you already had such an excellent util! I did cache the classes in a HashMap, unless you meant something else?

    EDIT 1:
    Ok, I see what you mean now. I'll try to shove everything into one class.
     
    #11 BananaPuncher714, Aug 30, 2017
    Last edited: Aug 30, 2017
  12. I have merged the two classes together and cached the methods and fields thanks to @MaTaMoR_ 's advice. I have also added support for shorts and floats, and this one really works on almost any version.
     
  13. Since Minecraft Beta 1.3, it has always been the default way minecraft handles and saves item data ex; Enchantments on items.
    @BananaPuncher714
    My resource has been floating around for a long time on Item NBT and how to use it. Although this is very useful for multiple versions.
    https://www.spigotmc.org/threads/tu...guide-to-itemstack-nbttags-attributes.131458/
    I think it is a requirement for this resource to provide support for NBTTagList's if it doesn't already since they are required to change the attributes of an item (Attackspeed and damage).
     
    • Like Like x 1
  14. Thanks for your awesome tutorial! I have added all the features that should allow better NBT data manipulation:). I have also added support for Entity editing.
     
    #15 BananaPuncher714, Aug 31, 2017
    Last edited: Aug 31, 2017
  15. Does this work to edit NBTTagLists?
     
  16. Code (Java):

        public static Class<?> getPrimitiveClass( Class<?> clazz ) {
            if ( clazz.getSimpleName().equals( "Byte" ) )
                return byte.class;
            if ( clazz.getSimpleName().equals( "Short" ) )
                return short.class;
            if ( clazz.getSimpleName().equals( "Integer" ) )
                return int.class;
            if ( clazz.getSimpleName().equals( "Long" ) )
                return long.class;
            if ( clazz.getSimpleName().equals( "Character" ) )
                return char.class;
            if ( clazz.getSimpleName().equals( "Float" ) )
                return float.class;
            if ( clazz.getSimpleName().equals( "Double" ) )
                return double.class;
            if ( clazz.getSimpleName().equals( "Boolean" ) )
                return boolean.class;
            if ( clazz.getSimpleName().equals( "Void" ) )
                return void.class;
            return clazz;
        }
     
    That can be smaller

    Code (Java):

        public static Class<?> getPrimitiveClass( Class<?> clazz ) {
            return Primitives.unwrap(clazz);
        }
     
     
    • Like Like x 1
  17. Yes.:) You would provide null or an int as a key to create/edit a list.
     
  18. @BananaPuncher714 , such code:
    Code (Text):
    ItemStack item = new ItemStack( Material.WOOD_HOE, 1 );
            item = NBTEditor.setItemTag(item,"TestValue","TestKey");
            Object val = NBTEditor.getItemTag(item, "TestKey");
           
            System.out.println("test "+val);
    returns exactly
    am i doing something wrong?:eek::eek:
     
  19. Hmm, I'm not quite sure. Did this always occur and are you using the latest version?

    EDIT 1: Wait, I dun goofed and I will fix it unless you want to try yourself. Inside the setItemTag method, after assigning the tag, I forgot to call the "setTag" method. I will fix it asap

    EDIT 2: Fixed:)
     
    #20 BananaPuncher714, Sep 8, 2017
    Last edited: Sep 8, 2017
    • Like Like x 1

Share This Page