From 786e0d9fafbc25fb577d7f2ebfae70d2e0f3e5f1 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 1d2eb4a6e..962183491 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -54,7 +54,7 @@ public final class ItemStack { // Paper end @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 d9574a9ac..93ae6dcd7 100644 --- a/src/main/java/net/minecraft/server/PacketDataSerializer.java +++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -253,6 +253,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); @@ -272,6 +281,16 @@ public class PacketDataSerializer extends ByteBuf { itemstack.setTag(this.l()); // 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 3a1d0deb0..1fcbbd698 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java @@ -58,6 +58,7 @@ public class PacketPlayOutMapChunk implements Packet { if (this.f() || (i & 1 << j) != 0) { NBTTagCompound nbttagcompound = tileentity.b(); + if (tileentity instanceof TileEntitySkull) { TileEntitySkull.sanitizeTileEntityUUID(nbttagcompound); } // Paper this.g.add(nbttagcompound); } diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java index 177cceb77..0882d82ce 100644 --- a/src/main/java/net/minecraft/server/TileEntitySkull.java +++ b/src/main/java/net/minecraft/server/TileEntitySkull.java @@ -142,9 +142,37 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa @Nullable @Override public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 4, this.b()); + return new PacketPlayOutTileEntityData(this.position, 4, sanitizeTileEntityUUID(this.b())); // Paper } + // 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 + @Override public NBTTagCompound b() { return this.save(new NBTTagCompound()); -- 2.25.0.windows.1