Example:
All dropped items will display as stone. DataWatcher ID bug.
https://www.youtube.com/watch?v=788153dV8Hk
Reproduce bug:
You just have to throw a splash potion before viewing any ground item (since your Minecraft was started) !
Then, go on a Minecraft Server (Vanilla, Spigot 1.9 or servers with 1.8/1.9 support) and drop an item on ground or throw a potion.
The item will be stone and the potion will display as water without real potion color.
In logs you will see:
"Item entity XXX has no item?!"
"ThrownPotion entity XXX has no item?!"
Cause:
This bug append when EntityPotion class was loaded before EntityItem class (so, when you see throwed potion before item on ground).
That's because DataWatcher/EntityMetadata ID was based on class load order in some cases.
Code is from Spigot 1.9, but it's the same on 1.9 client :
EntityItem.java
private static final DataWatcherObject<Optional<ItemStack>> c = DataWatcher.a(EntityItem.class, DataWatcherRegistry.f);
EntityPotion.java
private static final DataWatcherObject<Optional<ItemStack>> d = DataWatcher.a(EntityItem.class, DataWatcherRegistry.f);
This two codes call 'DataWatcher.a(EntityItem.class, DataWatcherRegistry.f);':
public static <T> DataWatcherObject<T> a(Class<? extends Entity> oclass, DataWatcherSerializer<T> datawatcherserializer)
{
int i;
int i;
if (a.containsKey(oclass))
{
i = ((Integer)a.get(oclass)).intValue() + 1;
}
else
{
int j = 0;
Class oclass1 = oclass;
while (oclass1 != Entity.class)
{
oclass1 = oclass1.getSuperclass();
if (a.containsKey(oclass1))
{
j = ((Integer)a.get(oclass1)).intValue() + 1;
break;
}
}
i = j;
}
if (i > 254) {
throw new IllegalArgumentException("Data value id is too big with " + i + "! (Max is " + 254 + ")");
}
a.put(oclass, Integer.valueOf(i));
return datawatcherserializer.a(i);
}
As you can see, variable i (the datawatcher index) is based on previous oclass value + 1.
So, if EntityItem load first, the id will be 5 and then when EntityPotion load the id will be 6.
But when EntityPotion load first the inverse occurs !
And when the inverse occurs the datawatcher ID was inverse and can't be synchronized with Minecraft servers.
Related issues
is duplicated by
Comments


Reproduced in 1.9.2. This is honestly one of the most absurd bugs I have seen so far.

This is a odd bug, well found (and isolated from the sea of other Minecraft weirdness) 🙂
This sounds like the cause of MC-93454