diff --git a/Spigot-Server-Patches/0331-Fix-client-rendering-skulls-from-same-user.patch b/Spigot-Server-Patches/0331-Fix-client-rendering-skulls-from-same-user.patch new file mode 100644 index 000000000..99693c3b0 --- /dev/null +++ b/Spigot-Server-Patches/0331-Fix-client-rendering-skulls-from-same-user.patch @@ -0,0 +1,130 @@ +From a70e309b53e72f03208ea7a96c2bb195a716d2ef Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Tue, 22 Nov 2016 00:40:42 -0500 +Subject: [PATCH] Fix client rendering skulls from same user + +See: https://github.com/PaperMC/Paper/issues/1304 + +Changes the UUID sent to client to be based on either +the texture payload, or random. + +This allows the client to render multiple skull textures from the same user, +for when different skins were used when skull was made. + +diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java +index e52014fd8f..da11ec1672 100644 +--- a/src/main/java/net/minecraft/server/ItemStack.java ++++ b/src/main/java/net/minecraft/server/ItemStack.java +@@ -44,7 +44,7 @@ public final class ItemStack { + private int e; + @Deprecated + private Item item; +- private NBTTagCompound tag; ++ NBTTagCompound tag; // Paper -> package private + private boolean h; + private EntityItemFrame i; + private ShapeDetectorBlock j; +diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java +index d04afceb70..b0e8ffc4b1 100644 +--- a/src/main/java/net/minecraft/server/PacketDataSerializer.java ++++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java +@@ -251,6 +251,15 @@ public class PacketDataSerializer extends ByteBuf { + CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); + // Spigot end + nbttagcompound = itemstack.getTag(); ++ // Paper start ++ if (nbttagcompound != null && nbttagcompound.hasKeyOfType("SkullOwner", 10)) { ++ NBTTagCompound owner = nbttagcompound.getCompound("SkullOwner"); ++ if (owner.hasKey("Id")) { ++ nbttagcompound.setString("SkullOwnerOrig", owner.getString("Id")); ++ TileEntitySkull.sanitizeUUID(owner); ++ } ++ } ++ // Paper end + } + + this.a(nbttagcompound); +@@ -271,6 +280,16 @@ public class PacketDataSerializer extends ByteBuf { + itemstack.setTag(this.j()); + // CraftBukkit start + if (itemstack.getTag() != null) { ++ // Paper start - Fix skulls of same owner - restore orig ID since we changed it on send to client ++ if (itemstack.tag.hasKey("SkullOwnerOrig")) { ++ NBTTagCompound owner = itemstack.tag.getCompound("SkullOwner"); ++ String ownerOrig = itemstack.tag.getString("SkullOwnerOrig"); ++ if (!owner.isEmpty() && !ownerOrig.isEmpty()) { ++ owner.setString("Id", ownerOrig); ++ } ++ itemstack.tag.remove("SkullOwnerOrig"); ++ } ++ // Paper end + CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); + } + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +index 1aa36156a8..c5f0b85309 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +@@ -38,6 +38,7 @@ public class PacketPlayOutMapChunk implements Packet { + + if (this.f() || (i & 1 << j) != 0) { + NBTTagCompound nbttagcompound = tileentity.aa_(); ++ if (tileentity instanceof TileEntitySkull) { TileEntitySkull.sanitizeTileEntityUUID(nbttagcompound); } // Paper + + this.e.add(nbttagcompound); + } +@@ -121,7 +122,7 @@ public class PacketPlayOutMapChunk implements Packet { + BiomeBase[] abiomebase = chunk.getBiomeIndex(); + + for (l = 0; l < abiomebase.length; ++l) { +- packetdataserializer.writeInt(BiomeBase.REGISTRY_ID.a((Object) abiomebase[l])); ++ packetdataserializer.writeInt(BiomeBase.REGISTRY_ID.a(abiomebase[l])); // Paper - decompile fix + } + } + +diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java +index 85fd8dab60..16a5537ce0 100644 +--- a/src/main/java/net/minecraft/server/TileEntitySkull.java ++++ b/src/main/java/net/minecraft/server/TileEntitySkull.java +@@ -143,9 +143,37 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa + return this.a; + } + ++ // Paper start ++ static NBTTagCompound sanitizeTileEntityUUID(NBTTagCompound cmp) { ++ NBTTagCompound owner = cmp.getCompound("Owner"); ++ if (!owner.isEmpty()) { ++ sanitizeUUID(owner); ++ } ++ return cmp; ++ } ++ ++ static void sanitizeUUID(NBTTagCompound owner) { ++ NBTTagCompound properties = owner.getCompound("Properties"); ++ NBTTagList list = null; ++ if (!properties.isEmpty()) { ++ list = properties.getList("textures", 10); ++ } ++ ++ if (list != null && !list.isEmpty()) { ++ String textures = ((NBTTagCompound)list.get(0)).getString("Value"); ++ if (textures != null && textures.length() > 3) { ++ String uuid = UUID.nameUUIDFromBytes(textures.getBytes()).toString(); ++ owner.setString("Id", uuid); ++ return; ++ } ++ } ++ owner.setString("Id", UUID.randomUUID().toString()); ++ } ++ // Paper end ++ + @Nullable + public PacketPlayOutTileEntityData getUpdatePacket() { +- return new PacketPlayOutTileEntityData(this.position, 4, this.aa_()); ++ return new PacketPlayOutTileEntityData(this.position, 4, sanitizeTileEntityUUID(this.aa_())); // Paper + } + + public NBTTagCompound aa_() { +-- +2.18.0 +