aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0266-Fix-client-rendering-skulls-from-same-user.patch
blob: 0178734bcb7e551efc1130d142fb8648031150cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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 d5350a382a70382a433e29a7c5a8879336c7568b..95dc7e4a604e613751eb16b127e3203027c8c26d 100644
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -60,7 +60,7 @@ public final class ItemStack {
     private int g;
     @Deprecated
     private Item item;
-    private NBTTagCompound tag;
+    NBTTagCompound tag; // Paper -> package private
     private boolean j;
     private Entity k;
     private ShapeDetectorBlock l;
diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java
index 6e049c2e2a142ce022b9dc278a3bb302f723e42c..7e116d83a62ef42e241ee9e05fdd7ecb30a2ed95 100644
--- a/src/main/java/net/minecraft/server/PacketDataSerializer.java
+++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java
@@ -274,9 +274,18 @@ public class PacketDataSerializer extends ByteBuf {
             if (item.usesDurability() || item.n()) {
                 // Spigot start - filter
                 itemstack = itemstack.cloneItemStack();
-                CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
+                //CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer needed due to NBT being supported
                 // Spigot end
                 nbttagcompound = itemstack.getTag();
+                // Paper start
+                if (nbttagcompound != null && nbttagcompound.hasKeyOfType("SkullOwner", 10)) {
+                    NBTTagCompound owner = nbttagcompound.getCompound("SkullOwner");
+                    if (owner.hasUUID("Id")) {
+                        nbttagcompound.setUUID("SkullOwnerOrig", owner.getUUID("Id"));
+                        TileEntitySkull.sanitizeUUID(owner);
+                    }
+                }
+                // Paper end
             }
 
             this.a(nbttagcompound);
@@ -296,7 +305,16 @@ public class PacketDataSerializer extends ByteBuf {
             itemstack.setTag(this.l());
             // CraftBukkit start
             if (itemstack.getTag() != null) {
-                CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
+                // 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");
+                    if (itemstack.tag.hasKey("SkullOwnerOrig")) {
+                        owner.map.put("Id", itemstack.tag.map.get("SkullOwnerOrig"));
+                        itemstack.tag.remove("SkullOwnerOrig");
+                    }
+                }
+                // Paper end
+                // CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer needed due to NBT being supported
             }
             // CraftBukkit end
             return itemstack;
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
index e336437207f9d6adbab69ef2785c129ff2ec1b36..72ff0a1e6428a1776f49c26e1715f5f2428ba242 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -60,6 +60,7 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
 
             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 4fae1b3274a96b871b39de083e9b28ab6129533f..579a81e521fdfabfa0318d06c6760a8ab7a88c1e 100644
--- a/src/main/java/net/minecraft/server/TileEntitySkull.java
+++ b/src/main/java/net/minecraft/server/TileEntitySkull.java
@@ -145,9 +145,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) {
+                UUID uuid = UUID.nameUUIDFromBytes(textures.getBytes());
+                owner.setUUID("Id", uuid);
+                return;
+            }
+        }
+        owner.setUUID("Id", UUID.randomUUID());
+    }
+    // Paper end
+
     @Override
     public NBTTagCompound b() {
         return this.save(new NBTTagCompound());