Entity NBT Tags Manipulation

Discussion in 'Plugin Development' started by DanielSturk, Mar 16, 2013.

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

    DanielSturk

    I wish to edit NBT Tags of a given Entity/LivingEntity/mob (Take your pick!), I search but I couldn't find any helpful things specific to this. Could anyone show me how/give me an example code?
    ANYTHING YOU CAN GIVE IS USEFUL,
    AFTER ALL, IT'S MORE THAN I KNOW. :) [cake]

    [Bump], and BTW I know how they work, I just need to know how to edit them for entitys/livingentitys/mobs

    [Bump]

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

    thebiologist13

    Hi!

    I use reflection to modify entity NBT.

    To get entity NBT data as a NBTTagCompound:
    Code:java
    1. public <T extends Entity> NBTTagCompound getEntityNBT(T entity) {
    2. NBTTagCompound compound = new NBTTagCompound();
    3.  
    4. if(!(entity instanceof Entity))
    5. return null;
    6.  
    7. net.minecraft.server.v1_5_R1.Entity nms = ((CraftEntity) entity).getHandle();
    8.  
    9. Class<? extends Object> clazz = nms.getClass();
    10. Method[] methods = clazz.getMethods();
    11. for (Method method : methods) {
    12. if ((method.getName() == "b")
    13. && (method.getParameterTypes().length == 1)
    14. && (method.getParameterTypes()[0] == NBTTagCompound.class)) {
    15. try {
    16. method.setAccessible(true);
    17. method.invoke(nms, compound);
    18. } catch (Exception e) {
    19. e.printStackTrace();
    20. }
    21. }
    22. }
    23.  
    24. if(compound.getString("id") == null || compound.getString("id").isEmpty()) {
    25. String id = getEntityName(entity.getType());
    26. compound.setString("id", id);
    27. }
    28.  
    29. return compound;
    30. }


    And to set back to an entity (mostly works, bugged for SpawnerMinecarts, but I am working it out):
    Code:java
    1. public void setEntityNBT(Entity e, NBTTagCompound n) {
    2. CraftEntity craft = ((CraftEntity) e);
    3. net.minecraft.server.v1_5_R1.Entity nms = craft.getHandle();
    4. Class<?> entityClass = nms.getClass();
    5. Method[] methods = entityClass.getMethods();
    6. for (Method method : methods) {
    7. if ((method.getName() == "a")
    8. && (method.getParameterTypes().length == 1)
    9. && (method.getParameterTypes()[0] == NBTTagCompound.class)) {
    10. try {
    11. method.setAccessible(true);
    12. method.invoke(nms, n);
    13. } catch (Exception ex) {
    14. ex.printStackTrace();
    15. }
    16. }
    17. }
    18. craft.setHandle(nms);
    19. }


    Be careful when you are experimenting with NBT though, once I crashed my client using it and corrupted the world save! :/

    I hope I could help!
    ~thebiologist13
     
  3. Offline

    Malikk

    Why would you use reflection on publicly accessible methods?

    Code:
     
    Entity bukkitEntity; //set else where
     
    net.minecraft.server.v1_5_R1.Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
     
    NBTTagCompound tag = new NBTTagCompound();
     
    //writes entity's nbt data to OUR tag object
    nmsEntity.c(tag);
     
    tag.doWhatever();
     
    //sets the entity's tag to OUR tag
    ((EntityLiving)nmsEntity).a(tag);
     
    
     
  4. Offline

    thebiologist13

    Oh! I have been using this method for a while. I wasn't aware they were public. I will try it out.

    ~thebiologist13
     
  5. Offline

    DanielSturk

    Thank you all so much! I used the first way, posted thebiologist13 because it was the only one posted when I checked this the first time. But thank you all so much!
     
Thread Status:
Not open for further replies.

Share This Page