diff --git a/Spigot-API-Patches/0057-Basic-PlayerProfile-API.patch b/Spigot-API-Patches/0057-Basic-PlayerProfile-API.patch index f0cad73ad0..a4fb2c8939 100644 --- a/Spigot-API-Patches/0057-Basic-PlayerProfile-API.patch +++ b/Spigot-API-Patches/0057-Basic-PlayerProfile-API.patch @@ -1,4 +1,4 @@ -From 0952cf855ca2b8bf45741e73250656ad452532c8 Mon Sep 17 00:00:00 2001 +From 15f696b679672e955cf4f3186130eb9afa2e0df6 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 15 Jan 2018 21:46:46 -0500 Subject: [PATCH] Basic PlayerProfile API @@ -7,10 +7,10 @@ Provides basic elements of a PlayerProfile to be used by future API/events diff --git a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java new file mode 100644 -index 00000000..0f44f98f +index 00000000..404fb468 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java -@@ -0,0 +1,97 @@ +@@ -0,0 +1,125 @@ +package com.destroystokyo.paper.profile; + +import com.mojang.authlib.GameProfile; @@ -43,6 +43,13 @@ index 00000000..0f44f98f + @Nonnull Set getProperties(); + + /** ++ * Check if the Profile has the specified property ++ * @param property Property name to check ++ * @return If the property is set ++ */ ++ boolean hasProperty(String property); ++ ++ /** + * Sets a property. If the property already exists, the previous one will be replaced + * @param property Property to set. + */ @@ -98,9 +105,30 @@ index 00000000..0f44f98f + /** + * If this profile is not complete, then make the API call to complete it. + * This is a blocking operation and should be done asynchronously. -+ * @return if the profile is now complete ++ * ++ * This will also complete textures. If you do not want to load textures, use {{@link #complete(boolean)}} ++ * @return if the profile is now complete (if you get rate limited, this operation may fail) + */ -+ boolean complete(); ++ default boolean complete() { ++ return complete(true); ++ } ++ ++ /** ++ * 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. ++ * @return if the profile is now complete (if you get rate limited, this operation may fail) ++ */ ++ boolean complete(boolean textures); ++ ++ /** ++ * Whether or not this Profile has textures associated to it ++ * @return If has a textures property ++ */ ++ default boolean hasTextures() { ++ return hasProperty("textures"); ++ } + + /** + * @deprecated Will be removed in 1.13 diff --git a/Spigot-Server-Patches/0214-Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/0214-Basic-PlayerProfile-API.patch index 1017c8c094..b3428dcd21 100644 --- a/Spigot-Server-Patches/0214-Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/0214-Basic-PlayerProfile-API.patch @@ -1,4 +1,4 @@ -From ece9ffa638c05b83affc7321bbe17f54774ff340 Mon Sep 17 00:00:00 2001 +From f925d0e5462649589e4dc8c9faf378d90f4b5df8 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 15 Jan 2018 22:11:48 -0500 Subject: [PATCH] Basic PlayerProfile API @@ -6,10 +6,10 @@ Subject: [PATCH] Basic PlayerProfile API 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 000000000..af6a81586 +index 000000000..616a7b218 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java -@@ -0,0 +1,248 @@ +@@ -0,0 +1,262 @@ +package com.destroystokyo.paper.profile; + +import com.destroystokyo.paper.PaperConfig; @@ -33,45 +33,36 @@ index 000000000..af6a81586 +public class CraftPlayerProfile implements PlayerProfile { + + private GameProfile profile; -+ private final PropertySet properties; ++ private final PropertySet properties = new PropertySet(); + + public CraftPlayerProfile(CraftPlayer player) { -+ GameProfile playerProfile = player.getHandle().getProfile(); -+ this.profile = new GameProfile(playerProfile.getId(), playerProfile.getName()); -+ copyProfileProperties(this.profile, this.profile); -+ this.properties = new PropertySet(); ++ this.profile = player.getHandle().getProfile(); + } + -+ /** -+ * Constructs a new Game Profile with the specified ID and name. -+ *

-+ * Either ID or name may be null/empty, but at least one must be filled. -+ * -+ * @param id Unique ID of the profile -+ * @param name Display name of the profile -+ * @throws IllegalArgumentException Both ID and name are either null or empty -+ */ + public CraftPlayerProfile(UUID id, String name) { -+ this(createGameProfile(id, name)); ++ this.profile = createGameProfile(id, name); ++ } ++ ++ public CraftPlayerProfile(GameProfile profile) { ++ this.profile = profile; + } + + private static GameProfile createGameProfile(UUID id, String name) { + new GameProfile(id, name); // Validate that both are not null + MinecraftServer server = MinecraftServer.getServer(); + UserCache userCache = server.getUserCache(); -+ GameProfile profile = null; -+ boolean isOnlineMode = server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); -+ if (id == null && isOnlineMode) { -+ profile = userCache.getProfile(name); -+ } ++ GameProfile profile; + -+ if (profile == null && name == null && id != null) { ++ if (id == null) { ++ profile = getProfileByName(name); ++ if (profile != null) { ++ id = profile.getId(); ++ } ++ } else { + profile = userCache.getProfile(id); -+ } -+ -+ if (profile == null && id == null && name != null && !isOnlineMode) { -+ // Make an OfflinePlayer using an offline mode UUID since the name has no profile -+ id = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)); ++ if (profile != null) { ++ name = profile.getName(); ++ } + } + + GameProfile resultProfile = new GameProfile(id, name); @@ -81,6 +72,19 @@ index 000000000..af6a81586 + return resultProfile; + } + ++ private static GameProfile getProfileByName(String name) { ++ final GameProfile profile; ++ final MinecraftServer server = MinecraftServer.getServer(); ++ boolean isOnlineMode = server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); ++ if (isOnlineMode) { ++ profile = server.getUserCache().getProfile(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); ++ } ++ return profile; ++ } ++ + private static void copyProfileProperties(GameProfile source, GameProfile target) { + PropertyMap properties = target.getProperties(); + properties.clear(); @@ -89,11 +93,85 @@ index 000000000..af6a81586 + } + } + -+ public CraftPlayerProfile(GameProfile profile) { -+ this.profile = profile; -+ this.properties = new PropertySet(); ++ @Override ++ public boolean hasProperty(String property) { ++ return profile.getProperties().containsKey(property); + } + ++ @Override ++ public void setProperty(ProfileProperty property) { ++ String name = property.getName(); ++ PropertyMap properties = profile.getProperties(); ++ properties.removeAll(name); ++ properties.put(name, new Property(name, property.getValue(), property.getSignature())); ++ } ++ ++ @Override ++ public void setProperties(Collection properties) { ++ properties.forEach(this::setProperty); ++ } ++ ++ @Override ++ public boolean removeProperty(String property) { ++ return !profile.getProperties().removeAll(property).isEmpty(); ++ } ++ ++ @Override ++ public void clearProperties() { ++ profile.getProperties().clear(); ++ } ++ ++ @Override ++ public boolean isComplete() { ++ return profile.isComplete(); ++ } ++ ++ public boolean complete(boolean textures) { ++ MinecraftServer server = MinecraftServer.getServer(); ++ String name = profile.getName(); ++ if (profile.getId() == null) { ++ profile = getProfileByName(name); ++ if (profile == null) { ++ throw new NullPointerException("Could not get UUID for Player " + name); ++ } ++ } ++ if (!profile.isComplete() || (textures && !hasTextures())) { ++ GameProfile result = server.getSessionService().fillProfileProperties(profile, true); ++ if (result != null) { ++ this.profile = result; ++ } ++ } ++ return profile.isComplete() && (!textures || hasTextures()); ++ } ++ ++ private static ProfileProperty toBukkit(Property property) { ++ return new ProfileProperty(property.getName(), property.getValue(), property.getSignature()); ++ } ++ ++ public static PlayerProfile asBukkitCopy(GameProfile gameProfile) { ++ CraftPlayerProfile profile = new CraftPlayerProfile(gameProfile.getId(), gameProfile.getName()); ++ copyProfileProperties(gameProfile, profile.profile); ++ return profile; ++ } ++ ++ public static PlayerProfile asBukkitMirror(GameProfile profile) { ++ return new CraftPlayerProfile(profile); ++ } ++ ++ public static Property asAuthlib(ProfileProperty property) { ++ return new Property(property.getName(), property.getValue(), property.getSignature()); ++ } ++ public static GameProfile asAuthlibCopy(PlayerProfile profile) { ++ CraftPlayerProfile craft = ((CraftPlayerProfile) profile); ++ return asAuthlib(craft.clone()); ++ } ++ ++ public static GameProfile asAuthlib(PlayerProfile profile) { ++ CraftPlayerProfile craft = ((CraftPlayerProfile) profile); ++ return craft.getGameProfile(); ++ } ++ ++ + public GameProfile getGameProfile() { + return profile; + } @@ -138,70 +216,6 @@ index 000000000..af6a81586 + return clone; + } + -+ @Override -+ public void setProperty(ProfileProperty property) { -+ String name = property.getName(); -+ PropertyMap properties = profile.getProperties(); -+ properties.removeAll(name); -+ properties.put(name, new Property(name, property.getValue(), property.getSignature())); -+ } -+ -+ @Override -+ public void setProperties(Collection properties) { -+ properties.forEach(this::setProperty); -+ } -+ -+ @Override -+ public boolean removeProperty(String property) { -+ return !profile.getProperties().removeAll(property).isEmpty(); -+ } -+ -+ @Override -+ public void clearProperties() { -+ profile.getProperties().clear(); -+ } -+ -+ @Override -+ public boolean isComplete() { -+ return profile.isComplete(); -+ } -+ -+ public boolean complete() { -+ if (!profile.isComplete()) { -+ GameProfile result = MinecraftServer.getServer().getSessionService().fillProfileProperties(profile, true); -+ if (result != null) { -+ this.profile = result; -+ } -+ } -+ return profile.isComplete(); -+ } -+ -+ private static ProfileProperty toBukkit(Property property) { -+ return new ProfileProperty(property.getName(), property.getValue(), property.getSignature()); -+ } -+ -+ public static PlayerProfile asBukkitCopy(GameProfile gameProfile) { -+ CraftPlayerProfile profile = new CraftPlayerProfile(gameProfile.getId(), gameProfile.getName()); -+ copyProfileProperties(gameProfile, profile.profile); -+ return profile; -+ } -+ -+ public static PlayerProfile asBukkitMirror(GameProfile profile) { -+ return new CraftPlayerProfile(profile); -+ } -+ -+ public static Property asAuthlib(ProfileProperty property) { -+ return new Property(property.getName(), property.getValue(), property.getSignature()); -+ } -+ public static GameProfile asAuthlibCopy(PlayerProfile profile) { -+ CraftPlayerProfile craft = ((CraftPlayerProfile) profile); -+ return asAuthlib(craft.clone()); -+ } -+ -+ public static GameProfile asAuthlib(PlayerProfile profile) { -+ CraftPlayerProfile craft = ((CraftPlayerProfile) profile); -+ return craft.getGameProfile(); -+ } + + private class PropertySet extends AbstractSet { + diff --git a/Spigot-Server-Patches/0278-Player.setPlayerProfile-API.patch b/Spigot-Server-Patches/0278-Player.setPlayerProfile-API.patch index d1233f6d55..fd1e94bd24 100644 --- a/Spigot-Server-Patches/0278-Player.setPlayerProfile-API.patch +++ b/Spigot-Server-Patches/0278-Player.setPlayerProfile-API.patch @@ -1,4 +1,4 @@ -From 7c932f5bcecf83c9dc4402042a9329fc1af62585 Mon Sep 17 00:00:00 2001 +From cebd684862b0e016056fc87f8ddff96dadbcd272 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 18 Mar 2018 12:29:48 -0400 Subject: [PATCH] Player.setPlayerProfile API @@ -18,8 +18,37 @@ index 4b82e43a8..35fde8b23 100644 private ItemStack bV; private final ItemCooldown bW; @Nullable +diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java +index 2842956bf..8aeded425 100644 +--- a/src/main/java/net/minecraft/server/LoginListener.java ++++ b/src/main/java/net/minecraft/server/LoginListener.java +@@ -41,7 +41,7 @@ public class LoginListener implements PacketLoginInListener, ITickable { + public final NetworkManager networkManager; + private LoginListener.EnumProtocolState g; + private int h; +- private GameProfile i; ++ private GameProfile i; private void setGameProfile(GameProfile profile) { i = profile; } private GameProfile getGameProfile() { return i; } // Paper - OBFHELPER + private final String j; + private SecretKey loginKey; + private EntityPlayer l; +@@ -294,12 +294,12 @@ public class LoginListener implements PacketLoginInListener, ITickable { + final org.bukkit.craftbukkit.CraftServer server = LoginListener.this.server.server; + + // Paper start +- PlayerProfile profile = Bukkit.createProfile(uniqueId, playerName); ++ PlayerProfile profile = CraftPlayerProfile.asBukkitMirror(getGameProfile()); + AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId, profile); + server.getPluginManager().callEvent(asyncEvent); + profile = asyncEvent.getPlayerProfile(); +- profile.complete(); +- i = CraftPlayerProfile.asAuthlibCopy(profile); ++ profile.complete(true); ++ setGameProfile(CraftPlayerProfile.asAuthlib(profile)); + playerName = i.getName(); + uniqueId = i.getId(); + // Paper end diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 21631c588..9c894185b 100644 +index 21631c588..1e73a3308 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1,6 +1,8 @@ @@ -82,7 +111,7 @@ index 21631c588..9c894185b 100644 + } + } + public PlayerProfile getPlayerProfile() { -+ return new CraftPlayerProfile(this); ++ return new CraftPlayerProfile(this).clone(); + } + // Paper end