1.8.8 Serialize Skull, skull-owner=null => ERROR (1.8)

Discussion in 'Spigot Plugin Development' started by kinglol12345, Feb 5, 2020.

Thread Status:
Not open for further replies.
  1. So the Problem is: If you serialize a Skull with no skull-owner in Version 1.8 it's getting validated and is an Error.

    Code (Text):
    Caused by: java.lang.NullPointerException: null value in entry: skull-owner=null
            at com.google.common.collect.CollectPreconditions.checkEntryNotNull(CollectPreconditions.java:33) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at com.google.common.collect.ImmutableMap.entryOf(ImmutableMap.java:135) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at com.google.common.collect.ImmutableMap$Builder.put(ImmutableMap.java:206) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.craftbukkit.v1_8_R3.inventory.CraftMetaSkull.serialize(CraftMetaSkull.java:173) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.craftbukkit.v1_8_R3.inventory.CraftMetaItem.serialize(CraftMetaItem.java:850) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]
            at org.bukkit.configuration.file.YamlRepresenter$RepresentConfigurationSerializable.representData(YamlRepresenter.java:33) ~[spigot-1.8.8.jar:git-Spigot-db6de12-18fbb24]

    Question already got asked multiple Times, but there is no Answer right now.


    It's already fixed in newer Spigot Versions, but I need a smooth workaround to provide 1.8 Users the use of Head Plugins. Someone got any nice Ideas or had the same Problem to solve?
     
  2. What about using a fake-UUID (either UUID#randomUUID or new UUID(0, 0) and then, during de-serialization checking, if the UID exists; if not it's a skull without an owner.
    If you use a custom texture, the Skull-UUID won't make any difference anyway and you can just use a random one.
     
  3. It's the first thing i thought about, too.
    But I seems like it changes the internal-Value in the SkullMeta too.
     
  4. Do you mean the texture-value?
    In that case, I suppose you could use reflection to just set the skull.
    Another possibility is to do a custom serialization and de-serialization (you'd only need to store the skull, owner and value)
     
  5. Thanks for you help. Yes it was the texture ^^.
    It is way simpler than I thought. Here's my workaround:

    Code (Java):
    if(paramItemStack.getItemMeta() instanceof SkullMeta) {
      SkullMeta skullMeta = ((SkullMeta) paramItemStack.getItemMeta());
        if (skullMeta.getOwner() == null) {
          try {
            Field profileField = skullMeta.getClass().getDeclaredField("profile");
            profileField.setAccessible(true);
            Object profile = profileField.get(skullMeta);

             Field name = profile.getClass().getDeclaredField("name");
             name.setAccessible(true);
             name.set(profile, "x");

             paramItemStack.setItemMeta(skullMeta);
           } catch (NoSuchFieldException | IllegalAccessException e) {
             e.printStackTrace();
           }
        }
    }
     
Thread Status:
Not open for further replies.