[Util] Edit ItemStack attributes, adding speed, damage or health bonuses.

Discussion in 'Resources' started by Comphenix, Jul 7, 2013.

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

    MTN

    Hmm, I get a NPE using https://gist.github.com/aadnk/6753244 and https://gist.github.com/aadnk/6754159

    Code:
    2013-10-21 05:33:17 [INFO] Maddis1337 issued server command: /krpg test
    2013-10-21 05:33:17 [SEVERE] null
    org.bukkit.command.CommandException: Unhandled exception executing command 'krpg' in plugin KRPG-Items v0.0.3
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46)
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:192)
    at org.bukkit.craftbukkit.v1_6_R3.CraftServer.dispatchCommand(CraftServer.java:523)
    at net.minecraft.server.v1_6_R3.PlayerConnection.handleCommand(PlayerConnection.java:959)
    at net.minecraft.server.v1_6_R3.PlayerConnection.chat(PlayerConnection.java:877)
    at net.minecraft.server.v1_6_R3.PlayerConnection.a(PlayerConnection.java:834)
    at net.minecraft.server.v1_6_R3.Packet3Chat.handle(SourceFile:49)
    at net.minecraft.server.v1_6_R3.NetworkManager.b(NetworkManager.java:296)
    at net.minecraft.server.v1_6_R3.PlayerConnection.e(PlayerConnection.java:116)
    at net.minecraft.server.v1_6_R3.ServerConnection.b(SourceFile:37)
    at net.minecraft.server.v1_6_R3.DedicatedServerConnection.b(SourceFile:30)
    at net.minecraft.server.v1_6_R3.MinecraftServer.t(MinecraftServer.java:592)
    at net.minecraft.server.v1_6_R3.DedicatedServer.t(DedicatedServer.java:227)
    at net.minecraft.server.v1_6_R3.MinecraftServer.s(MinecraftServer.java:488)
    at net.minecraft.server.v1_6_R3.MinecraftServer.run(MinecraftServer.java:421)
    at net.minecraft.server.v1_6_R3.ThreadServerApplication.run(SourceFile:583)
    Caused by: java.lang.NullPointerException
    at net.minecraft.server.v1_6_R3.NBTTagCompound.clone(SourceFile:265)
    at net.minecraft.server.v1_6_R3.NBTTagList.clone(SourceFile:90)
    at net.minecraft.server.v1_6_R3.NBTTagCompound.clone(SourceFile:265)
    at net.minecraft.server.v1_6_R3.ItemStack.cloneItemStack(ItemStack.java:265)
    at org.bukkit.craftbukkit.v1_6_R3.inventory.CraftItemStack.asCraftCopy(CraftItemStack.java:67)
    at org.bukkit.craftbukkit.v1_6_R3.inventory.CraftInventory.firstPartial(CraftInventory.java:254)
    at org.bukkit.craftbukkit.v1_6_R3.inventory.CraftInventory.addItem(CraftInventory.java:281)
    at de.kaleydra.krpg.KRPGCommand.onCommand(KRPGCommand.java:100)
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
    ... 15 more
    from KRPGCommand:100
    Code:java
    1.  
    2. item.addAttribute(AttributeType.GENERIC_MOVEMENT_SPEED, 5.0); // instanceof KRPGItem
    3. final ItemStack item2 = item.getItem();
    4. ((Player)sender).getInventory().addItem(item2);
    5.  


    from KRPGItem:
    Code:java
    1.  
    2. //<AttributeType,Value>
    3. Map<String,Double> attributes = new HashMap<String,Double>();
    4.  
    5. [...]
    6.  
    7. public ItemStack getItem(){
    8. ItemStack item = new ItemStack(material);
    9. ItemMeta itemMeta = item.getItemMeta();
    10. itemMeta.setDisplayName(customName);
    11. itemMeta.setLore(getLore());
    12. item.setItemMeta(itemMeta);
    13.  
    14. return applyAttributes(item);
    15. }
    16.  
    17. public ItemStack applyAttributes(ItemStack item){
    18. if(this.attributes == null || this.attributes.isEmpty())
    19. return item;
    20.  
    21. Attributes attributes = new Attributes(item);
    22. for(String type:this.attributes.keySet()){
    23. attributes.add(Attribute.newBuilder().type(new AttributeType(type)).amount(this.attributes.get(type)).build());
    24. }
    25. return attributes.getStack();
    26. }
    27.  
     
  2. Offline

    Comphenix

    Have you tried adding a name to these attributes, like in my example?

    That might be what's causing the NPE. Somehow, a null name gets assigned to the NBT data.

    If not, could you print the content of the NBT tag? If you're using the ProtocolLib version (or native version), then all that's required is to call the toString() method on the NbtList attributes, and print the result.
     
  3. Offline

    MTN

    Jepp, that was it :) Works like charm!

    EDIT: Is there a way to edit attributes of entities, too?
     
  4. Offline

    Comphenix

    Good to hear. :)

    Of course, it should probably have complained about the missing name in the first place (which I've now added). But the library was never intended to last very long, only until Bukkit releases a proper API ...

    Not with this library, but you can do it with NMS.
     
  5. Offline

    MTN

    I wonder if it has the effect if I give an item with attributes to an entity via the equipment... Anyone experience with that?
     
  6. Offline

    soulofw0lf

    @Comphenix is it possible to get an update of this for 1.7.2? getting an error trying to use it.

    Code:
    us.iluthi.soulofw0lf.ultimatesurvival.utility.NbtFactory.getMethod(NbtFactory.java:715) ~[?:?]
    02.12 12:38:02 [Server] INFO Caused by: java.lang.IllegalStateException: Unable to find method createTag ([byte, class java.lang.String]).
    referring to

    Code:java
    1. private static Method getMethod(int requireMod, int bannedMod, Class<?> clazz, String methodName, Class<?>... params) {
    2. for (Method method : clazz.getDeclaredMethods()) {
    3. // Limitation: Doesn't handle overloads
    4. if ((method.getModifiers() & requireMod) == requireMod &&
    5. (method.getModifiers() & bannedMod) == 0 &&
    6. (methodName == null || method.getName().equals(methodName)) &&
    7. Arrays.equals(method.getParameterTypes(), params)) {
    8.  
    9. method.setAccessible(true);
    10. return method;
    11. }
    12. }
    13. // Search in every superclass
    14. if (clazz.getSuperclass() != null)
    15. return getMethod(requireMod, bannedMod, clazz.getSuperclass(), methodName, params);
    16. throw new IllegalStateException(String.format(
    17. "Unable to find method %s (%s).", methodName, Arrays.asList(params)));
    18. }
     
  7. Offline

    Comphenix

    This is because the NBT library in Minecraft no longer stores tag names in the NBT tags themselves, but as keys in NBTTagCompound. Thus, NBTBase.createTag has changed signature from createTag(byte tagId, String tagName) to createTag(byte tagId):
    Code:java
    1. protected static NBTBase createTag(byte paramByte) {
    2. // etc.
    3. }

    To solve this, simply remove String.class here (in private NbtFactory()):
    Code:java
    1. NBT_CREATE_TAG = getMethod(Modifier.STATIC, 0, BASE_CLASS, "createTag", byte.class);

    Then update the createNbtTag method:
    Code:
    private Object createNbtTag(NbtType type, Object value) {
        Object tag = invokeMethod(NBT_CREATE_TAG, null, (byte)type.id);
     
        if (value != null) {
            setFieldValue(getDataField(type, tag), tag, value);
        }
        return tag;
    }
    I'd love to do this myself, but I'm pretty preoccupied with updating ProtocolLib at the moment. I'll finish it later.
     
  8. Offline

    soulofw0lf

    @Comphenix - Completely understand man. Proto-Lib is an awesome project and it's a good thing it has such a dedicated dev for it :)

    Everyone else
    ok so i tried updating it myself. Since comp is busy if anyone else wants to take a crack at it here's the nbt factory with his recommended changes

    https://gist.github.com/soulofwolf/91c606f5e1276625c068

    here's the Attribute class
    https://gist.github.com/soulofwolf/7d9a210723ad3631098e

    and here's what i wrote to build items with it

    Code:java
    1. public class Stats {
    2. public static ItemStack createItem(ItemStack iS, String stat, double value){
    3. if (stat.equalsIgnoreCase("health")){
    4. Attributes attributes = new Attributes(iS);
    5. attributes.add(Attributes.Attribute.newBuilder().name("Health")
    6. .type(Attributes.AttributeType.GENERIC_MAX_HEALTH).amount(value).build());
    7. }
    8. if (stat.equalsIgnoreCase("speed")){
    9. Attributes attributes = new Attributes(iS);
    10.  
    11. attributes.add(Attributes.Attribute.newBuilder().name("Speed")
    12. .type(Attributes.AttributeType.GENERIC_MOVEMENT_SPEED).amount(value).build());
    13.  
    14. }
    15. if (stat.equalsIgnoreCase("damage")){
    16. Attributes attributes = new Attributes(iS);
    17.  
    18. attributes.add(Attributes.Attribute.newBuilder().name("Damage")
    19. .type(Attributes.AttributeType.GENERIC_ATTACK_DAMAGE).amount(value).build());
    20.  
    21. }
    22. if (stat.equalsIgnoreCase("knockback")){
    23. Attributes attributes = new Attributes(iS);
    24.  
    25. attributes.add(Attributes.Attribute.newBuilder().name("KnockBack")
    26. .type(Attributes.AttributeType.GENERIC_KNOCKBACK_RESISTANCE).amount(value).build());
    27.  
    28. }
    29. return iS;
    30. }
    31. }


    still erroring out completely due to a null object from the save and load from the nbt factory and i have no clue what to do for it. So if any of you aren't busy and can take a look at it it would be appreciated.
     
  9. Offline

    xigsag

    Just bumping to see if this will be updated?
     
  10. Offline

    Comphenix

  11. Offline

    xigsag

    I must have missed that. Thanks!
     
  12. Offline

    Bammerbom

    Epic library!
     
Thread Status:
Not open for further replies.

Share This Page