diff --git a/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch index 59a1ff797a..0fb3a82843 100644 --- a/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch @@ -7,10 +7,10 @@ Establishes base extension of profile systems for future edits too diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java new file mode 100644 -index 0000000000000000000000000000000000000000..b151a13c1b9058eb057081ef8a64558028443a07 +index 0000000000000000000000000000000000000000..5eee712e4c9230b10a969daee9fd8b4eec9bf6c9 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java -@@ -0,0 +1,280 @@ +@@ -0,0 +1,285 @@ +package com.destroystokyo.paper.profile; + +import com.destroystokyo.paper.PaperConfig; @@ -151,9 +151,6 @@ index 0000000000000000000000000000000000000000..b151a13c1b9058eb057081ef8a645580 + } + + public boolean completeFromCache(boolean lookupName) { -+ if (profile.isComplete()) { -+ return true; -+ } + MinecraftServer server = MinecraftServer.getServer(); + String name = profile.getName(); + UserCache userCache = server.getUserCache(); @@ -167,14 +164,17 @@ index 0000000000000000000000000000000000000000..b151a13c1b9058eb057081ef8a645580 + profile = new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name); + } + if (profile != null) { ++ // if old has it, assume its newer, so overwrite, else use cached if it was set and ours wasn't ++ copyProfileProperties(this.profile, profile); + this.profile = profile; + } + } + -+ if (profile.getName() == null) { -+ // If we need textures, skip this check, as we will get it below anyways. ++ if (profile.getName() == null || !hasTextures()) { + GameProfile profile = userCache.getProfile(this.profile.getId()); + if (profile != null) { ++ // if old has it, assume its newer, so overwrite, else use cached if it was set and ours wasn't ++ copyProfileProperties(this.profile, profile); + this.profile = profile; + } + } @@ -189,22 +189,27 @@ index 0000000000000000000000000000000000000000..b151a13c1b9058eb057081ef8a645580 + if (isOnlineMode && (!isCompleteFromCache || textures && !hasTextures())) { + GameProfile result = server.getSessionService().fillProfileProperties(profile, true); + if (result != null) { -+ this.profile = result; ++ copyProfileProperties(result, this.profile, true); + } ++ server.getUserCache().saveProfile(this.profile); + } + return profile.isComplete() && (!isOnlineMode || !textures || hasTextures()); + } + + private static void copyProfileProperties(GameProfile source, GameProfile target) { ++ copyProfileProperties(source, target, false); ++ } ++ ++ private static void copyProfileProperties(GameProfile source, GameProfile target, boolean clearTarget) { + PropertyMap sourceProperties = source.getProperties(); ++ PropertyMap targetProperties = target.getProperties(); ++ if (clearTarget) targetProperties.clear(); + if (sourceProperties.isEmpty()) { + return; + } -+ PropertyMap properties = target.getProperties(); -+ properties.clear(); + + for (Property property : sourceProperties.values()) { -+ properties.put(property.getName(), property); ++ targetProperties.put(property.getName(), property); + } + } + @@ -450,8 +455,50 @@ index ed32242bd169e9f28607942aa31aa48a5799b215..54f80cb8e1b771f2a493543e04f8bc83 public MinecraftSessionService getMinecraftSessionService() { return this.minecraftSessionService; } +diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java +index 177cceb77f8783fe93ba7e4342de9c589f155c1b..e2544aeb5a28fd98a4dc162227276b23a99424fc 100644 +--- a/src/main/java/net/minecraft/server/TileEntitySkull.java ++++ b/src/main/java/net/minecraft/server/TileEntitySkull.java +@@ -158,6 +158,7 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa + private void f() { + // Spigot start + GameProfile profile = this.gameProfile; ++ if (profile.isComplete() && profile.getProperties().containsKey("textures")) return; // Paper + b(profile, new Predicate() { + + @Override +@@ -178,7 +179,16 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa + } else if (MinecraftServer.getServer() == null) { + callback.apply(gameprofile); + } else { +- GameProfile profile = skinCache.getIfPresent(gameprofile.getName().toLowerCase(java.util.Locale.ROOT)); ++ // Paper start ++ com.destroystokyo.paper.profile.CraftPlayerProfile paperProfile = new com.destroystokyo.paper.profile.CraftPlayerProfile(gameprofile); ++ if (sync) { ++ // might complete by cache, but if not, go ahead and do it now, avoid the code below ++ paperProfile.complete(true); ++ } else { ++ paperProfile.completeFromCache(); ++ } ++ GameProfile profile = paperProfile.getGameProfile(); ++ // Paper end + if (profile != null && Iterables.getFirst(profile.getProperties().get("textures"), (Object) null) != null) { + callback.apply(profile); + +@@ -187,7 +197,10 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa + Callable callable = new Callable() { + @Override + public GameProfile call() { +- final GameProfile profile = skinCache.getUnchecked(gameprofile.getName().toLowerCase(java.util.Locale.ROOT)); ++ // Paper start ++ paperProfile.complete(true); ++ final GameProfile profile = paperProfile.getGameProfile(); ++ // Paper end + MinecraftServer.getServer().processQueue.add(new Runnable() { + @Override + public void run() { diff --git a/src/main/java/net/minecraft/server/UserCache.java b/src/main/java/net/minecraft/server/UserCache.java -index 581199e6dcddb3692ccc6b6cf6c42fa5ef1f5e7e..a072222bc5b8b1b62990bce35034b09ebf270865 100644 +index 581199e6dcddb3692ccc6b6cf6c42fa5ef1f5e7e..39d2f83531d539fb96824c2e6a9018c12ea75272 100644 --- a/src/main/java/net/minecraft/server/UserCache.java +++ b/src/main/java/net/minecraft/server/UserCache.java @@ -43,7 +43,7 @@ public class UserCache { @@ -463,7 +510,15 @@ index 581199e6dcddb3692ccc6b6cf6c42fa5ef1f5e7e..a072222bc5b8b1b62990bce35034b09e private final Map e = new java.util.concurrent.ConcurrentHashMap<>(); // Paper private final Deque f = new java.util.concurrent.LinkedBlockingDeque(); // CraftBukkit private final GameProfileRepository g; -@@ -165,6 +165,13 @@ public class UserCache { +@@ -104,6 +104,7 @@ public class UserCache { + return UserCache.c; + } + ++ public void saveProfile(GameProfile gameprofile) { a(gameprofile); } // Paper - OBFHELPER + public void a(GameProfile gameprofile) { + this.a(gameprofile, (Date) null); + } +@@ -165,6 +166,13 @@ public class UserCache { return usercache_usercacheentry == null ? null : usercache_usercacheentry.a(); } @@ -477,7 +532,7 @@ index 581199e6dcddb3692ccc6b6cf6c42fa5ef1f5e7e..a072222bc5b8b1b62990bce35034b09e @Nullable public GameProfile getProfile(UUID uuid) { UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) this.e.get(uuid); -@@ -273,7 +280,7 @@ public class UserCache { +@@ -273,7 +281,7 @@ public class UserCache { class UserCacheEntry { @@ -525,3 +580,19 @@ index f01bd38d0b600a69224f610fd77a542ec6d1c322..95f4abddf57eb8c59cb5a5410b8d551d + } // Paper end } +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java +index 4fb27cc7ed062696239f75b6f85ddb0a31866568..52c8d31590ea8e355395fa95cf690cc3770f5f71 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java +@@ -71,6 +71,11 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { + } + + private void setProfile(GameProfile profile) { ++ // Paper start ++ com.destroystokyo.paper.profile.CraftPlayerProfile paperProfile = new com.destroystokyo.paper.profile.CraftPlayerProfile(profile); ++ paperProfile.completeFromCache(); ++ profile = paperProfile.getGameProfile(); ++ // Paper end + this.profile = profile; + this.serializedProfile = (profile == null) ? null : GameProfileSerializer.serialize(new NBTTagCompound(), profile); + } diff --git a/Spigot-Server-Patches/0191-Add-setPlayerProfile-API-for-Skulls.patch b/Spigot-Server-Patches/0191-Add-setPlayerProfile-API-for-Skulls.patch index 03e42d479a..2e893431db 100644 --- a/Spigot-Server-Patches/0191-Add-setPlayerProfile-API-for-Skulls.patch +++ b/Spigot-Server-Patches/0191-Add-setPlayerProfile-API-for-Skulls.patch @@ -48,7 +48,7 @@ index 20588598386a4f479e6a58b294149bed789c63ce..ecc32c2fb1e8e1ac03074102b982adb4 public BlockFace getRotation() { BlockData blockData = getBlockData(); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java -index 4fb27cc7ed062696239f75b6f85ddb0a31866568..96d62bbf883cf589509d51ac02fbe11a452dce64 100644 +index 52c8d31590ea8e355395fa95cf690cc3770f5f71..2a3c86b0cbce0c37ebd8cace138c72c99f7455ea 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java @@ -3,6 +3,8 @@ package org.bukkit.craftbukkit.inventory; @@ -68,7 +68,7 @@ index 4fb27cc7ed062696239f75b6f85ddb0a31866568..96d62bbf883cf589509d51ac02fbe11a @DelegateDeserialization(SerializableMeta.class) class CraftMetaSkull extends CraftMetaItem implements SkullMeta { -@@ -133,6 +136,19 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { +@@ -138,6 +141,19 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { return hasOwner() ? profile.getName() : null; }