From 03240a3fdd8c69c59408bb6ccf187139964bdad2 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 23 Jun 2020 04:53:02 -0400 Subject: [PATCH] Fix Player skulls for offline mode servers Always use online mode for them in Profile API calls Adds new API to profile API to let you control online mode yourself Fixes #3594 --- .../Basic-PlayerProfile-API.patch | 32 ++++++++++++++++++ .../Basic-PlayerProfile-API.patch | 33 +++++++++++-------- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Spigot-API-Patches/Basic-PlayerProfile-API.patch b/Spigot-API-Patches/Basic-PlayerProfile-API.patch index c28657d172..7583bbbec2 100644 --- a/Spigot-API-Patches/Basic-PlayerProfile-API.patch +++ b/Spigot-API-Patches/Basic-PlayerProfile-API.patch @@ -128,6 +128,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + boolean completeFromCache(); + + /** ++ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls ++ * Does not account for textures. ++ * ++ * @param onlineMode Treat this as online mode or not ++ * @return If the profile is now complete (has UUID and Name) ++ */ ++ boolean completeFromCache(boolean onlineMode); ++ ++ /** ++ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls ++ * Does not account for textures. ++ * ++ * @param lookupUUID If only name is supplied, should we do a UUID lookup ++ * @param onlineMode Treat this as online mode or not ++ * @return If the profile is now complete (has UUID and Name) ++ */ ++ boolean completeFromCache(boolean lookupUUID, boolean onlineMode); ++ ++ /** + * If this profile is not complete, then make the API call to complete it. + * This is a blocking operation and should be done asynchronously. + * @@ -143,12 +162,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * This is a blocking operation and should be done asynchronously. + * + * Optionally will also fill textures. ++ * ++ * Online mode will be automatically determined + * @param textures controls if we should fill the profile with texture properties + * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) + */ + boolean complete(boolean textures); + + /** ++ * If this profile is not complete, then make the API call to complete it. ++ * This is a blocking operation and should be done asynchronously. ++ * ++ * Optionally will also fill textures. ++ * @param textures controls if we should fill the profile with texture properties ++ * @param onlineMode Treat this server as online mode or not ++ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) ++ */ ++ boolean complete(boolean textures, boolean onlineMode); ++ ++ /** + * Whether or not this Profile has textures associated to it + * @return If has a textures property + */ diff --git a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch index 79329ad63c..a15cdbb8dc 100644 --- a/Spigot-Server-Patches/Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/Basic-PlayerProfile-API.patch @@ -149,18 +149,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @Override + public boolean completeFromCache() { -+ return completeFromCache(false); ++ MinecraftServer server = MinecraftServer.getServer(); ++ return completeFromCache(false, server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode)); + } + -+ public boolean completeFromCache(boolean lookupName) { ++ public boolean completeFromCache(boolean onlineMode) { ++ return completeFromCache(false, onlineMode); ++ } ++ ++ public boolean completeFromCache(boolean lookupUUID, boolean onlineMode) { + MinecraftServer server = MinecraftServer.getServer(); + String name = profile.getName(); + UserCache userCache = server.getUserCache(); + if (profile.getId() == null) { + final GameProfile profile; -+ boolean isOnlineMode = server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); -+ if (isOnlineMode) { -+ profile = lookupName ? userCache.getProfile(name) : userCache.getProfileIfCached(name); ++ if (onlineMode) { ++ profile = lookupUUID ? userCache.getProfile(name) : userCache.getProfileIfCached(name); + } else { + // Make an OfflinePlayer using an offline mode UUID since the name has no profile + profile = new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name); @@ -185,17 +189,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + public boolean complete(boolean textures) { + MinecraftServer server = MinecraftServer.getServer(); ++ return complete(textures, server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode)); ++ } ++ public boolean complete(boolean textures, boolean onlineMode) { ++ MinecraftServer server = MinecraftServer.getServer(); + -+ boolean isOnlineMode = server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); -+ boolean isCompleteFromCache = this.completeFromCache(true); -+ if (isOnlineMode && (!isCompleteFromCache || textures && !hasTextures())) { ++ boolean isCompleteFromCache = this.completeFromCache(false, onlineMode); ++ if (onlineMode && (!isCompleteFromCache || textures && !hasTextures())) { + GameProfile result = server.getSessionService().fillProfileProperties(profile, true); + if (result != null) { + copyProfileProperties(result, this.profile, true); + } + server.getUserCache().saveProfile(this.profile); + } -+ return profile.isComplete() && (!isOnlineMode || !textures || hasTextures()); ++ return profile.isComplete() && (!onlineMode || !textures || hasTextures()); + } + + private static void copyProfileProperties(GameProfile source, GameProfile target) { @@ -478,9 +485,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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); ++ paperProfile.complete(true, true); + } else { -+ paperProfile.completeFromCache(); ++ paperProfile.completeFromCache(false, true); + } + GameProfile profile = paperProfile.getGameProfile(); + // Paper end @@ -493,7 +500,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public GameProfile call() { - final GameProfile profile = skinCache.getUnchecked(gameprofile.getName().toLowerCase(java.util.Locale.ROOT)); + // Paper start -+ paperProfile.complete(true); ++ paperProfile.complete(true, true); + final GameProfile profile = paperProfile.getGameProfile(); + // Paper end MinecraftServer.getServer().processQueue.add(new Runnable() { @@ -593,7 +600,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + if (profile != null) { + com.destroystokyo.paper.profile.CraftPlayerProfile paperProfile = new com.destroystokyo.paper.profile.CraftPlayerProfile(profile); -+ paperProfile.completeFromCache(); ++ paperProfile.completeFromCache(false, true); + profile = paperProfile.getGameProfile(); + } + // Paper end