Solved Skull texture isSimilar NPE

Discussion in 'Spigot Plugin Development' started by Steve362, Feb 22, 2020.

  1. I'm trying to update my plugin to 1.15.2 using base64 skull textures, this code works in prior versions (1.14 and below) however I seem to get an NPE when comparing two identical skulls.

    My code:
    Code (Java):
           @Override
           public void onEnable() {
              ItemStack head1 = new ItemStack(Material.PLAYER_HEAD);

              UUID uuid = UUID.randomUUID();
              GameProfile profile1 = new GameProfile(uuid, null);
              profile1.getProperties().put("textures", new Property("textures", "some random skin value"));

              setProfile(head1, profile1);

              ItemStack head2 = head1.clone();

              if(head1.isSimilar(head2)) { // Fails here
                  System.out.println("Is similar");
              }

           }

           private void setProfile(ItemStack item, GameProfile profile) {
              ItemMeta meta = item.getItemMeta();
              try {
                 Field field = meta.getClass().getDeclaredField("profile");
                 field.setAccessible(true);
                 field.set(meta, profile);
              } catch (NoSuchFieldException | IllegalAccessException ex) {
                 ex.printStackTrace();
              }
              item.setItemMeta(meta);
           }
        }
    I am using the latest build, any help appreciated.
     
    #1 Steve362, Feb 22, 2020
    Last edited: Feb 22, 2020
  2. Switch if(head1.equals(head2)) { for if(head1.isSimilar(head2)) {
     
  3. I forgot to change that back. Same error:

    Code (Text):

    [10:57:25 ERROR]: Error occurred while enabling SkullTest v0.0.1 (Is it up to date?)
    java.lang.NullPointerException: null
            at org.bukkit.craftbukkit.v1_15_R1.inventory.CraftMetaSkull.equalsCommon(CraftMetaSkull.java:220) ~[patched_1.15.2.jar:git-Paper-112]
            at org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemFactory.equals(CraftItemFactory.java:307) ~[patched_1.15.2.jar:git-Paper-112]
            at org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemFactory.equals(CraftItemFactory.java:294) ~[patched_1.15.2.jar:git-Paper-112]
            at org.bukkit.inventory.ItemStack.isSimilar(ItemStack.java:293) ~[patched_1.15.2.jar:git-Paper-112]
            at me.tango.skulltest.Main.onEnable(Main.java:34) ~[?:?]
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263) ~[patched_1.15.2.jar:git-Paper-112]
            at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:337) ~[patched_1.15.2.jar:git-Paper-112]
            at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:435) ~[patched_1.15.2.jar:git-Paper-112]
            at org.bukkit.craftbukkit.v1_15_R1.CraftServer.enablePlugin(CraftServer.java:470) ~[patched_1.15.2.jar:git-Paper-112]
            at org.bukkit.craftbukkit.v1_15_R1.CraftServer.enablePlugins(CraftServer.java:384) ~[patched_1.15.2.jar:git-Paper-112]
            at net.minecraft.server.v1_15_R1.MinecraftServer.a(MinecraftServer.java:482) ~[patched_1.15.2.jar:git-Paper-112]
            at net.minecraft.server.v1_15_R1.DedicatedServer.init(DedicatedServer.java:298) ~[patched_1.15.2.jar:git-Paper-112]
            at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:885) ~[patched_1.15.2.jar:git-Paper-112]
            at java.lang.Thread.run(Thread.java:834) [?:?]
    [10:57:25 INFO]: [SkullTest] Disabling SkullTest v0.0.1

     
     
  4. Check which one of the item stacks is null
     
  5. None of them are null, I am able to get them ingame. Only get NPE when using any method that uses equals method. Such as isSimilar, and checking if an arraylist contains the skull. Its really confusing, especially considering it works on 1.14 fine.
     
  6. Can we see the imports and the NPE code?
     
  7. I've shown where the NPE happens in the main post, my imports are:
    Code (Text):
    import java.lang.reflect.Field;
    import java.util.UUID;

    import org.bukkit.Material;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;

    import com.mojang.authlib.GameProfile;
    import com.mojang.authlib.properties.Property;
     
  8. I copyes your code and changed it to this
    Code (Java):
        @Override
        public void onEnable() {
            ItemStack head1 = new ItemStack(Material.PLAYER_HEAD);
            ItemStack head2 = new ItemStack(Material.PLAYER_HEAD);

            GameProfile profile1 = new GameProfile(UUID.randomUUID(), null);
            GameProfile profile2 = new GameProfile(UUID.randomUUID(), null);
            profile1.getProperties().put("textures", new Property("textures", "some random skin value"));
            profile2.getProperties().put("textures", new Property("textures", "some random skin value"));
         
            setProfile(head1, profile1);
            setProfile(head2, profile2);

            System.out.println(String.valueOf(head1));
            System.out.println(String.valueOf(head2));
         
            if (head1.isSimilar(head2)) {
                System.out.println("Is similar");
            }

        }

        private void setProfile(ItemStack item, GameProfile profile) {
            ItemMeta meta = item.getItemMeta();
            try {
                Field field = meta.getClass().getDeclaredField("profile");
                field.setAccessible(true);
                field.set(meta, profile);
            } catch (NoSuchFieldException | IllegalAccessException ex) {
                ex.printStackTrace();
            }
            item.setItemMeta(meta);
        }
    And now I get
    Code (Text):
    [12:31:20 INFO]: [Tests] Enabling Tests v1.0
    [12:31:20 ERROR]: Error occurred while enabling Tests v1.0 (Is it up to date?)
    java.lang.NullPointerException: null
    Thats the hole error
    What is pretty strange, I don't really know what is happening
     
    • Like Like x 1
  9. Thank you for trying, perhaps it is a bug. Or maybe there is a different way of setting skull textures in 1.15, but I can't find anything about it.
     
  10. Try this

    Code (Java):
    import java.lang.reflect.Field;
    import java.util.UUID;
    import org.bukkit.Material;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.SkullMeta;
    import com.mojang.authlib.GameProfile;
    import com.mojang.authlib.properties.Property;

    public class GetHead {

        public ItemStack getHead(String name) {
            for (Heads head : Heads.values()) {
                if (head.getName().equalsIgnoreCase(name)) {
                    return head.getItemStack();
                }
            }
            return null;
        }

        public static ItemStack createSkull(String url, String name) {
            ItemStack head = new ItemStack(Material.PLAYER_HEAD);
            if (url.isEmpty())
                return head;

            SkullMeta headMeta = (SkullMeta) head.getItemMeta();
            GameProfile profile = new GameProfile(UUID.randomUUID(), null);

            profile.getProperties().put("textures", new Property("textures", url));

            try {
                Field profileField = headMeta.getClass().getDeclaredField("profile");
                profileField.setAccessible(true);
                profileField.set(headMeta, profile);

            } catch (IllegalArgumentException | NoSuchFieldException | SecurityException | IllegalAccessException error) {
                error.printStackTrace();
            }
            head.setItemMeta(headMeta);
            return head;
        }

    }
     
    Code (Java):
    import org.bukkit.inventory.ItemStack;

    public enum Heads {
        INFO1("MzU3NDcwMTBkODRhYTU2NDgzYjc1ZjYyNDNkOTRmMzRjNTM0NjAzNTg0YjJjYzY4YTQ1YmYzNjU4NDAxMDVmZCJ9fX0==", "info1"),
        INFO2("MTY0MzlkMmUzMDZiMjI1NTE2YWE5YTZkMDA3YTdlNzVlZGQyZDUwMTVkMTEzYjQyZjQ0YmU2MmE1MTdlNTc0ZiJ9fX0==", "info2"),
        INFO3("ZDAxYWZlOTczYzU0ODJmZGM3MWU2YWExMDY5ODgzM2M3OWM0MzdmMjEzMDhlYTlhMWEwOTU3NDZlYzI3NGEwZiJ9fX0==", "info3"),
        INFO4("Y2Q5MWY1MTI2NmVkZGM2MjA3ZjEyYWU4ZDdhNDljNWRiMDQxNWFkYTA0ZGFiOTJiYjc2ODZhZmRiMTdmNGQ0ZSJ9fX0==", "info4");
    // An enum with all your heads.

        private ItemStack item;
        private String idTag;
        private String prefix = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUv";

        private Heads(String texture, String id) {
            item = GetHead.createSkull(prefix + texture, id);
            idTag = id;
        }

        public ItemStack getItemStack() {
            return item;
        }

        public String getName() {
            return idTag;
        }

    }
    Usage:
    Code (Java):
    ItemStack head = new GetHead().getHead(id);
    //Or
    Heads.ID.getItemStack();
    I don't remember where I got this code but it may work
     
    #12 Nemo_64, Feb 22, 2020
    Last edited: Feb 22, 2020
  11. Thanks, I will try it out now
     
  12. Doesn't work :cry: I'm still unable to compare skulls. I'm starting to believe it is a bug in 1.15.2
     
  13. I just don't know thats happening. Sorry for not being able to help
    Maybe the users that will conect in like 9H that now are sleeping/working can help
     
    • Friendly Friendly x 1
  14. Thanks again for trying
     
  15. Bump (please help)
     
  16. Bump, anyone know why this happens?
     
  17. You have to use the CraftMetaSkull#setProfile method instead of directly setting the field, if i remember correctly it had something to do with this issue and calling the method will handle it for you.
     
  18. Thanks for the reply, I can't seem to find anything on CraftMetaSkull#setProfile on google or in the javadoc, can you explain how I can use this method?