-
Bug
-
Resolution: Fixed
-
Minor
-
None
-
None
-
None
The issue: Skull items with a skull owner profile containing a custom texture, no owner name (and usually a random uuid), which can for example be created with the vanilla give command as shown below, are not properly serialized and deserialized to/from configuration files.
This ticket is probably related to SPIGOT-583. The linked ticket did only mention skull items without attached profile (and was marked as fixed).
This ticket however is about config serialization of skull items with 'custom/modified/unusual' profile, which people seem to use for creating skull items with custom textures. (This is probably what was intended by the linked ticket in the first place).
I did test this issue by using the example skull item created by the following command. Similar commands are also created by this online tool: http://www.dragnoz.com/custom-head-block-generator/
/give @p skull 1 3
{display:
,
SkullOwner:{
Id:"60dbfcd2-4f2e-49ff-91ed-e8e6242dd0b2",
Properties:{
textures:
[
]
}
}
}
Some plugin trying to store this skull item in a configuration file will experience a NPE during serialization (example at the end of this ticket).
So the first part of this issue is that craftbukkit is currently trying to store null (the custom profiles don't have an owner name) in the ImmutableMapBuilder here (which doesn't accept null as value) here: https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java#159
The second part of this issue would then be to properly store and restore other values of the custom profile, like the uuid and the texture component (which don't get currently stored as far as I can tell from a quick look at the source code).
[15:58:45 WARN]: Exception in thread "Craft Scheduler Thread - 6"
[15:58:45 WARN]: org.apache.commons.lang.UnhandledException: Plugin Shopkeepers v1.63-SNAPSHOT generated an exception while executing task 1650
at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftAsyncTask.run(CraftAsyn
cTask.java:56)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: null value in entry: skull-owner=null
at com.google.common.collect.CollectPreconditions.checkEntryNotNull(Coll
ectPreconditions.java:33)
at com.google.common.collect.ImmutableMap.entryOf(ImmutableMap.java:135)
at com.google.common.collect.ImmutableMap$Builder.put(ImmutableMap.java:
206)
at org.bukkit.craftbukkit.v1_8_R3.inventory.CraftMetaSkull.serialize(Cra
ftMetaSkull.java:173)
at org.bukkit.craftbukkit.v1_8_R3.inventory.CraftMetaItem.serialize(Craf
tMetaItem.java:850)
at org.bukkit.configuration.file.YamlRepresenter$RepresentConfigurationS
erializable.representData(YamlRepresenter.java:33)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepr
esenter.java:94)
at org.yaml.snakeyaml.representer.BaseRepresenter.representMapping(BaseR
epresenter.java:156)
at org.yaml.snakeyaml.representer.SafeRepresenter$RepresentMap.represent
Data(SafeRepresenter.java:304)
at org.bukkit.configuration.file.YamlRepresenter$RepresentConfigurationS
erializable.representData(YamlRepresenter.java:35)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepr
esenter.java:94)
at org.yaml.snakeyaml.representer.BaseRepresenter.representMapping(BaseR
epresenter.java:156)
at org.yaml.snakeyaml.representer.SafeRepresenter$RepresentMap.represent
Data(SafeRepresenter.java:304)
at org.bukkit.configuration.file.YamlRepresenter$RepresentConfigurationS
ection.representData(YamlRepresenter.java:23)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepr
esenter.java:94)
at org.yaml.snakeyaml.representer.BaseRepresenter.representMapping(BaseR
epresenter.java:156)
at org.yaml.snakeyaml.representer.SafeRepresenter$RepresentMap.represent
Data(SafeRepresenter.java:304)
at org.bukkit.configuration.file.YamlRepresenter$RepresentConfigurationS
ection.representData(YamlRepresenter.java:23)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepr
esenter.java:94)
at org.yaml.snakeyaml.representer.BaseRepresenter.representMapping(BaseR
epresenter.java:156)
at org.yaml.snakeyaml.representer.SafeRepresenter$RepresentMap.represent
Data(SafeRepresenter.java:304)
at org.bukkit.configuration.file.YamlRepresenter$RepresentConfigurationS
ection.representData(YamlRepresenter.java:23)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepr
esenter.java:94)
at org.yaml.snakeyaml.representer.BaseRepresenter.representMapping(BaseR
epresenter.java:156)
at org.yaml.snakeyaml.representer.SafeRepresenter$RepresentMap.represent
Data(SafeRepresenter.java:304)
at org.yaml.snakeyaml.representer.BaseRepresenter.representData(BaseRepr
esenter.java:94)
at org.yaml.snakeyaml.representer.BaseRepresenter.represent(BaseRepresen
ter.java:64)
at org.yaml.snakeyaml.Yaml.dumpAll(Yaml.java:242)
at org.yaml.snakeyaml.Yaml.dumpAll(Yaml.java:206)
at org.yaml.snakeyaml.Yaml.dump(Yaml.java:181)
at org.bukkit.configuration.file.YamlConfiguration.saveToString(YamlConf
iguration.java:40)
at com.nisovin.shopkeepers.ShopkeepersPlugin.saveDataToFile(ShopkeepersP
lugin.java:1392)
at com.nisovin.shopkeepers.ShopkeepersPlugin.access$1200(ShopkeepersPlug
in.java:62)
at com.nisovin.shopkeepers.ShopkeepersPlugin$11.run(ShopkeepersPlugin.ja
va:1302)
at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftTask.run(CraftTask.java
:71)
at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftAsyncTask.run(CraftAsyn
cTask.java:53)
... 3 more