Solved Monster-Egg in Inventory

Discussion in 'Spigot Help' started by Bean900, May 3, 2017.

  1. Hello Spigotusers,

    When I create an itemstack with a monster egg and add it to an inventory, the object is automatically expanded in the metadata by the attribute id = skeleton.

    Now I am looking after this object in the inventory. However, I can not find it because my reference has no id.
    Code (Text):

    ItemStack{MONSTER_EGG x 1, SPAWN_EGG_META:{meta-type=SPAWN_EGG, display-name=§2Item: §fMONSTER_EGG, lore=[§aBuy: §f1, §aUser: §cAdminshop]}}
    ItemStack{MONSTER_EGG x 1, SPAWN_EGG_META:{meta-type=SPAWN_EGG, display-name=§2Item: §fMONSTER_EGG, lore=[§aBuy: §f1, §aUser: §cAdminshop], id=skeleton}}

    How can i add this ID in my Itemstack?
     
    #1 Bean900, May 3, 2017
    Last edited: May 4, 2017
  2. What language is that?
     
  3. This ist the Syso of the .toString() Method of the Object ItemStack
     
  4. Try to use:
    Code (Text):
    ItemStack item =
    ItemStack{MONSTER_EGG x 1, SPAWN_EGG_META:{meta-type=SPAWN_EGG, display-name=§2Item: §fMONSTER_EGG, lore=[§aBuy: §f1, §aUser: §cAdminshop], id=skeleton}}
    But i dont think works. Sorry for the question bit why you have to use the format .toString()?
     
    • Funny Funny x 1
  5. I use the .toString() method for debugging. So i can see what variables are different.

    Thanks Michel_0,

    Code (Text):
            Material material = Material.getMaterial(this.materialName);
            ItemStack itemStack = new ItemStack(material, this.amount, this.data);
            if (material == Material.MONSTER_EGG) {
                SpawnEggMeta meta = (SpawnEggMeta) itemStack.getItemMeta();
                meta.setSpawnedType(EntityType.fromId(this.data));
                itemStack.setItemMeta(meta);
            }
    now the id is set and both objects seems to be the same in the .toString method.
    However, the .equals and .isSimilar methods are still false.
    What could be the problem now...
     
    #6 Bean900, May 4, 2017
    Last edited: May 4, 2017
  6. Show us some more code.
    From the first ItemStack at first instance, until the final ItemStack, that seems to differ somehow.
     
  7. Code (Text):

    Material material = Material.MONSTER_EGG;
    ItemStack itemStack = new ItemStack(material, 1, (short) 51);
    SpawnEggMeta meta = (SpawnEggMeta) itemStack.getItemMeta();
    meta.setSpawnedType(EntityType.SKELETON);
    itemStack.setItemMeta(meta);

    Inventory inventory = Bukkit.createInventory(null, 6 * 9);

    inventory.setItem(1, itemStack);

    if (inventory.getItem(1).equals(itemStack)) {
    System.out.println("Now it works <3");
    } else {
    System.out.println("WHY :(");
    }
     
    Here is a code example was so should run.
     
  8. Tested and confirmed. Prints out "WHY :(".

    Little modifed and debugged Version:
    Code (Java):
        private String getAllItemData(ItemStack item) {
            return CraftItemStack.asNMSCopy(item).save(new NBTTagCompound()).toString();
        }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arguments) {
            if (sender instanceof Player) {
                Material material = Material.MONSTER_EGG;
                ItemStack itemStack = new ItemStack(material, 1, (short) 51);
                SpawnEggMeta meta = (SpawnEggMeta) itemStack.getItemMeta();
                meta.setSpawnedType(EntityType.SKELETON);
                itemStack.setItemMeta(meta);
                Inventory inventory = Bukkit.createInventory(null, 6 * 9);
                inventory.setItem(1, itemStack);
                if (inventory.getItem(1).equals(itemStack)) {
                    sender.sendMessage("ItemStacks are equal.");
                } else {
                    sender.sendMessage("ItemStacks are NOT equal:");
                    sender.sendMessage("A: " + this.getAllItemData(itemStack));
                    sender.sendMessage("B: " + this.getAllItemData(inventory.getItem(1)));
                }
            }
            return true;
        }
    Prints out:
    Code (Text):
    [18:38:43][18:38:49] [Client thread/INFO]: [CHAT] ItemStacks are NOT equal:
    [18:38:49] [Client thread/INFO]: [CHAT] A: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    [18:38:49] [Client thread/INFO]: [CHAT] B: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    -> unequal
    Code (Java):
        private String getAllItemData(ItemStack item) {
            return CraftItemStack.asNMSCopy(item).save(new NBTTagCompound()).toString();
        }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arguments) {
            if (sender instanceof Player) {
                ItemStack eggA = new ItemStack(Material.MONSTER_EGG, 1);
                SpawnEggMeta metaA = (SpawnEggMeta) eggA.getItemMeta();
                metaA.setSpawnedType(EntityType.SKELETON);
                eggA.setItemMeta(metaA);
                Inventory inventory = Bukkit.createInventory(null, 54);
                inventory.setItem(1, eggA);
                ItemStack eggB = inventory.getItem(1);
                if (eggA.equals(eggB)) {
                    sender.sendMessage("ItemStacks are equal.");
                } else {
                    sender.sendMessage("ItemStacks are NOT equal:");
                    sender.sendMessage("A: " + this.getAllItemData(eggA));
                    sender.sendMessage("B: " + this.getAllItemData(eggB));
                }
            }
            return true;
        }
    Code (Text):
    [18:46:36] [Client thread/INFO]: [CHAT] ItemStacks are equal.
    -> equal

    So now where is the difference between the first & second?...
    Code (Java):
        private String getAllItemData(ItemStack item) {
            return CraftItemStack.asNMSCopy(item).save(new NBTTagCompound()).toString();
        }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arguments) {
            if (sender instanceof Player) {
             
                // (2) -> Then i secondly changed this back and they are NOT equal anymore, so that's the problem... but why...
                ItemStack eggA = new ItemStack(Material.MONSTER_EGG, 1, (short) 51);

                // (3a) -> Then i thirdly added some debug to find out what's what
                sender.sendMessage("Debug 1: " + this.getAllItemData(eggA));
             
                SpawnEggMeta metaA = (SpawnEggMeta) eggA.getItemMeta();
                metaA.setSpawnedType(EntityType.SKELETON);
                eggA.setItemMeta(metaA);
             
                // (3b) -> Then i thirdly added some debug to find out what's what
                sender.sendMessage("Debug 2: " + this.getAllItemData(eggA));
             
                Inventory inventory = Bukkit.createInventory(null, 54);
                inventory.setItem(1, eggA);
             
                // (3c) -> Then i thirdly added some debug to find out what's what
                sender.sendMessage("Debug 3: " + this.getAllItemData(eggA));
             
                ItemStack eggB = inventory.getItem(1);
             
                // (1) -> At first i changed this back to, but they're still equal
                if (inventory.getItem(1).equals(eggA)) {
             
                    sender.sendMessage("ItemStacks are equal.");
                } else {
                    sender.sendMessage("ItemStacks are NOT equal:");
                    sender.sendMessage("A: " + this.getAllItemData(eggA));
                    sender.sendMessage("B: " + this.getAllItemData(eggB));
                }
            }
            return true;
        }
    Prints out:
    Code (Text):
    [18:58:48] [Client thread/INFO]: [CHAT] Debug 1: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    [18:58:48] [Client thread/INFO]: [CHAT] Debug 2: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    [18:58:48] [Client thread/INFO]: [CHAT] Debug 3: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    [18:58:48] [Client thread/INFO]: [CHAT] ItemStacks are NOT equal:
    [18:58:48] [Client thread/INFO]: [CHAT] A: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    [18:58:48] [Client thread/INFO]: [CHAT] B: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    -> The damage value 51 doesn't seem to get applied on the NMS item (damage value), but that's not the problem... because both got damage 0.

    So:
    Code (Java):
        private String getAllItemData(ItemStack item) {
            return CraftItemStack.asNMSCopy(item).save(new NBTTagCompound()).toString();
        }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arguments) {
            if (sender instanceof Player) {
                ItemStack eggA = new ItemStack(Material.MONSTER_EGG, 1, (short) 51);
                sender.sendMessage("Debug 1: " + Short.toString(eggA.getDurability()));
                SpawnEggMeta metaA = (SpawnEggMeta) eggA.getItemMeta();
                metaA.setSpawnedType(EntityType.SKELETON);
                eggA.setItemMeta(metaA);
                Inventory inventory = Bukkit.createInventory(null, 54);
                inventory.setItem(1, eggA);
                ItemStack eggB = inventory.getItem(1);
                sender.sendMessage("Debug 2: " + Short.toString(eggB.getDurability()));
                if (inventory.getItem(1).equals(eggA)) {
                    sender.sendMessage("ItemStacks are equal.");
                } else {
                    sender.sendMessage("ItemStacks are NOT equal:");
                    sender.sendMessage("A: " + this.getAllItemData(eggA));
                    sender.sendMessage("B: " + this.getAllItemData(eggB));
                }
            }
            return true;
        }
    Prints out:
    Code (Text):
    [19:11:21] [Client thread/INFO]: [CHAT] Debug 1: 51
    [19:11:21] [Client thread/INFO]: [CHAT] Debug 2: 0
    [19:11:21] [Client thread/INFO]: [CHAT] ItemStacks are NOT equal:
    [19:11:21] [Client thread/INFO]: [CHAT] A: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    [19:11:21] [Client thread/INFO]: [CHAT] B: {id:"minecraft:spawn_egg",Count:1b,tag:{EntityTag:{id:"minecraft:skeleton"}},Damage:0s}
    -> Finally we got it identified.

    • The NMS item instance does not get the damage value (most likely, because 0 is the only valid damage for SpawnEggs sine the spawned entity gets defined by NBT data, no more the damage value)
    • Putting the item into an inventory ("org.bukkit.craftbukkit.v1_11_R1.inventory.CraftInventory#setItem") uses the NMS item instance (using damage = 0)
    • The Bukkit item keeps damage = 51
    • Getting the item out of the inventory generates a new bukkit item out of the NMS item (now both damage = 0)
    • Comparing it to the original causes damage mismatch (51 != 0)
    • "org.bukkit.inventory.ItemStack#toString" does not print out the damage value, that's why you didn't see it
    EDIT: Confirmed, "net.minecraft.server.v1_11_R1.ItemStack#setData" checks, if the specific item should have durability. If not, it won't be set (spawn eggs should not since idk 1.9 or so).
     
    #9 Michel_0, May 5, 2017
    Last edited: May 5, 2017
    • Agree Agree x 1
  9. WOW! Many many thanks for this detailed response and the time you invested there. Has helped me very much and I will try the next few days in my code.