Update Profile Lookup Events to use new PlayerProfile API

This commit is contained in:
Aikar 2018-01-19 00:03:09 -05:00
parent a7da447b88
commit 17bec29ef0
4 changed files with 168 additions and 93 deletions

View file

@ -7,12 +7,14 @@ 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 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 new file mode 100644
index 00000000..fd8788be index 00000000..f3868f94
--- /dev/null --- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java +++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package com.destroystokyo.paper.profile; +package com.destroystokyo.paper.profile;
+ +
+import com.mojang.authlib.GameProfile;
+
+import javax.annotation.Nonnull; +import javax.annotation.Nonnull;
+import javax.annotation.Nullable; +import javax.annotation.Nullable;
+import java.util.Collection; +import java.util.Collection;
@ -92,6 +94,12 @@ index 00000000..fd8788be
+ * @return Does this profile have Name, UUID and Textures filled in + * @return Does this profile have Name, UUID and Textures filled in
+ */ + */
+ boolean isComplete(); + boolean isComplete();
+
+ /**
+ * @deprecated Will be removed in 1.13
+ */
+ @Deprecated
+ GameProfile getGameProfile();
+} +}
diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
new file mode 100644 new file mode 100644

View file

@ -26,12 +26,13 @@ index c8b37997..13994dc2 100644
<artifactId>fastutil-lite</artifactId> <artifactId>fastutil-lite</artifactId>
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java diff --git a/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java
new file mode 100644 new file mode 100644
index 00000000..37e957f4 index 00000000..e4b36255
--- /dev/null --- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java +++ b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package com.destroystokyo.paper.event.profile; +package com.destroystokyo.paper.event.profile;
+ +
+import com.destroystokyo.paper.profile.PlayerProfile;
+import com.mojang.authlib.GameProfile; +import com.mojang.authlib.GameProfile;
+import org.bukkit.Bukkit; +import org.bukkit.Bukkit;
+import org.bukkit.event.Event; +import org.bukkit.event.Event;
@ -49,17 +50,10 @@ index 00000000..37e957f4
+public class LookupProfileEvent extends Event { +public class LookupProfileEvent extends Event {
+ +
+ private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList();
+ /**
+ * @deprecated will be removed with 1.13
+ */
+ @Deprecated
+ private final GameProfile profile;
+ +
+ /** + private final PlayerProfile profile;
+ * @deprecated will be removed with 1.13 +
+ */ + public LookupProfileEvent(@Nonnull PlayerProfile profile) {
+ @Deprecated
+ public LookupProfileEvent(@Nonnull GameProfile profile) {
+ super(!Bukkit.isPrimaryThread()); + super(!Bukkit.isPrimaryThread());
+ this.profile = profile; + this.profile = profile;
+ } + }
@ -71,6 +65,14 @@ index 00000000..37e957f4
+ @Deprecated + @Deprecated
+ @Nonnull + @Nonnull
+ public GameProfile getProfile() { + public GameProfile getProfile() {
+ return profile.getGameProfile();
+ }
+
+ /**
+ * @return The profile that was recently looked up. This profile can be mutated
+ */
+ @Nonnull
+ public PlayerProfile getPlayerProfile() {
+ return profile; + return profile;
+ } + }
+ +
@ -85,25 +87,24 @@ index 00000000..37e957f4
+} +}
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java diff --git a/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
new file mode 100644 new file mode 100644
index 00000000..455ffaa1 index 00000000..0a657904
--- /dev/null --- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java +++ b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package com.destroystokyo.paper.event.profile; +package com.destroystokyo.paper.event.profile;
+ +
+import com.destroystokyo.paper.profile.PlayerProfile;
+import com.destroystokyo.paper.profile.ProfileProperty;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap; +import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.GameProfileRepository;
+import com.mojang.authlib.ProfileLookupCallback;
+import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.Property;
+import com.mojang.authlib.properties.PropertyMap;
+import org.bukkit.Bukkit; +import org.bukkit.Bukkit;
+import org.bukkit.event.Event; +import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList; +import org.bukkit.event.HandlerList;
+ +
+import javax.annotation.Nonnull; +import javax.annotation.Nonnull;
+import javax.annotation.Nullable; +import javax.annotation.Nullable;
+import java.util.HashSet;
+import java.util.Set; +import java.util.Set;
+import java.util.UUID; +import java.util.UUID;
+ +
@ -122,11 +123,7 @@ index 00000000..455ffaa1
+ private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList();
+ private final String name; + private final String name;
+ private UUID uuid; + private UUID uuid;
+ /** + private Set<ProfileProperty> properties = new HashSet<>();
+ * @deprecated will be removed with 1.13
+ */
+ @Deprecated
+ private PropertyMap properties = new PropertyMap();
+ +
+ public PreLookupProfileEvent(@Nonnull String name) { + public PreLookupProfileEvent(@Nonnull String name) {
+ super(!Bukkit.isPrimaryThread()); + super(!Bukkit.isPrimaryThread());
@ -156,9 +153,9 @@ index 00000000..455ffaa1
+ /** + /**
+ * Sets the UUID for this player name. This will skip the initial API call to find the players UUID. + * Sets the UUID for this player name. This will skip the initial API call to find the players UUID.
+ * + *
+ * However, if Profile Properties are needed by the server, you must also set them or else an API call will still be made. + * However, if Profile Properties are needed by the server, you must also set them or else an API call might still be made.
+ * + *
+ * @param uuid the UUID to set on the {@link GameProfile} or null to reset + * @param uuid the UUID to set for the profile or null to reset
+ */ + */
+ public void setUUID(@Nullable UUID uuid) { + public void setUUID(@Nullable UUID uuid) {
+ this.uuid = uuid; + this.uuid = uuid;
@ -167,13 +164,18 @@ index 00000000..455ffaa1
+ /** + /**
+ * Get the properties for this profile + * Get the properties for this profile
+ * + *
+ * @return the property map to attach to the new {@link GameProfile} + * @return the property map to attach to the new {@link PlayerProfile}
+ * @deprecated will be removed with 1.13 + * @deprecated will be removed with 1.13
+ */ + */
+ @Deprecated + @Deprecated
+ @Nonnull + @Nonnull
+ public Multimap<String, Property> getProperties() { + public Multimap<String, Property> getProperties() {
+ return properties; + Multimap<String, Property> props = ArrayListMultimap.create();
+
+ for (ProfileProperty property : properties) {
+ props.put(property.getName(), new Property(property.getName(), property.getValue(), property.getSignature()));
+ }
+ return props;
+ } + }
+ +
+ /** + /**
@ -183,8 +185,10 @@ index 00000000..455ffaa1
+ */ + */
+ @Deprecated + @Deprecated
+ public void setProperties(Multimap<String, Property> properties) { + public void setProperties(Multimap<String, Property> properties) {
+ this.properties = new PropertyMap(); + this.properties = new HashSet<>();
+ this.properties.putAll(properties); + properties.values().forEach(property -> {
+ this.properties.add(new ProfileProperty(property.getName(), property.getValue(), property.getSignature()));
+ });
+ } + }
+ +
+ /** + /**
@ -194,7 +198,36 @@ index 00000000..455ffaa1
+ */ + */
+ @Deprecated + @Deprecated
+ public void addProperties(Multimap<String, Property> properties) { + public void addProperties(Multimap<String, Property> properties) {
+ this.properties.putAll(properties); + properties.values().forEach(property -> {
+ this.properties.add(new ProfileProperty(property.getName(), property.getValue(), property.getSignature()));
+ });
+ }
+
+ /**
+ * @return The currently pending prepopulated properties.
+ * Any property in this Set will be automatically prefilled on this Profile
+ */
+ public Set<ProfileProperty> getProfileProperties() {
+ return this.properties;
+ }
+
+ /**
+ * Clears any existing prepopulated properties and uses the supplied properties
+ * Any property in this Set will be automatically prefilled on this Profile
+ * @param properties The properties to add
+ */
+ public void setProfileProperties(Set<ProfileProperty> properties) {
+ this.properties = new HashSet<>();
+ this.properties.addAll(properties);
+ }
+
+ /**
+ * Adds any properties currently missing to the prepopulated properties set, replacing any that already were set.
+ * Any property in this Set will be automatically prefilled on this Profile
+ * @param properties The properties to add
+ */
+ public void addProfileProperties(Set<ProfileProperty> properties) {
+ this.properties.addAll(properties);
+ } + }
+ +
+ @Override + @Override
@ -206,57 +239,5 @@ index 00000000..455ffaa1
+ return handlers; + return handlers;
+ } + }
+ +
+ /**
+ * Wraps the Profile Repository so we can intercept all lookups
+ * @deprecated will be removed with 1.13
+ */
+ @Deprecated
+ public static GameProfileRepository wrapProfileRepository(final GameProfileRepository orig) {
+ return (names, agent, callback) -> {
+ Set<String> unfoundNames = Sets.newHashSet();
+ for (String name : names) {
+ PreLookupProfileEvent event = new PreLookupProfileEvent(name);
+ event.callEvent();
+ if (event.getUUID() != null) {
+ // Plugin provided UUI, we can skip network call.
+ GameProfile gameprofile = new GameProfile(event.getUUID(), name);
+ // We might even have properties!
+ gameprofile.getProperties().putAll(event.getProperties());
+ callback.onProfileLookupSucceeded(gameprofile);
+ } else {
+ unfoundNames.add(name);
+ }
+ }
+
+ // Some things were not found.... Proceed to look up.
+ if (!unfoundNames.isEmpty() && orig != null) {
+ String[] namesArr = unfoundNames.toArray(new String[unfoundNames.size()]);
+ orig.findProfilesByNames(namesArr, agent, new PreProfileLookupCallback(callback));
+ }
+ };
+ }
+
+ /**
+ * @deprecated will be removed with 1.13
+ */
+ @Deprecated
+ private static class PreProfileLookupCallback implements ProfileLookupCallback {
+ private final ProfileLookupCallback callback;
+
+ PreProfileLookupCallback(ProfileLookupCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onProfileLookupSucceeded(GameProfile gameProfile) {
+ new LookupProfileEvent(gameProfile).callEvent();
+ callback.onProfileLookupSucceeded(gameProfile);
+ }
+
+ @Override
+ public void onProfileLookupFailed(GameProfile gameProfile, Exception e) {
+ callback.onProfileLookupFailed(gameProfile, e);
+ }
+ }
+} +}
-- --

View file

@ -4,11 +4,11 @@ Date: Mon, 15 Jan 2018 22:11:48 -0500
Subject: [PATCH] Basic PlayerProfile API Subject: [PATCH] Basic PlayerProfile API
diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftGameProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftGameProfile.java 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 new file mode 100644
index 000000000..9891d8f06 index 000000000..6e9a6a2e6
--- /dev/null --- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/profile/CraftGameProfile.java +++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package com.destroystokyo.paper.profile; +package com.destroystokyo.paper.profile;
+ +
@ -23,7 +23,7 @@ index 000000000..9891d8f06
+import java.util.UUID; +import java.util.UUID;
+import java.util.stream.Collectors; +import java.util.stream.Collectors;
+ +
+public class CraftGameProfile implements PlayerProfile { +public class CraftPlayerProfile implements PlayerProfile {
+ +
+ private final GameProfile profile; + private final GameProfile profile;
+ +
@ -36,7 +36,7 @@ index 000000000..9891d8f06
+ * @param name Display name of the profile + * @param name Display name of the profile
+ * @throws IllegalArgumentException Both ID and name are either null or empty + * @throws IllegalArgumentException Both ID and name are either null or empty
+ */ + */
+ public CraftGameProfile(UUID id, String name) { + public CraftPlayerProfile(UUID id, String name) {
+ this.profile = new GameProfile(id, name); + this.profile = new GameProfile(id, name);
+ } + }
+ +
@ -53,7 +53,7 @@ index 000000000..9891d8f06
+ @Nonnull + @Nonnull
+ @Override + @Override
+ public Set<ProfileProperty> getProperties() { + public Set<ProfileProperty> getProperties() {
+ return profile.getProperties().values().stream().map(this::toBukkit).collect(Collectors.toSet()); + return profile.getProperties().values().stream().map(CraftPlayerProfile::toBukkit).collect(Collectors.toSet());
+ } + }
+ +
+ @Nullable + @Nullable
@ -105,12 +105,22 @@ index 000000000..9891d8f06
+ return profile.isComplete(); + return profile.isComplete();
+ } + }
+ +
+ private ProfileProperty toBukkit(Property property) { + private static ProfileProperty toBukkit(Property property) {
+ return new ProfileProperty(property.getName(), property.getValue(), property.getSignature()); + return new ProfileProperty(property.getName(), property.getValue(), property.getSignature());
+ } + }
+
+ public static PlayerProfile from(GameProfile gameProfile) {
+ PlayerProfile profile = new CraftPlayerProfile(gameProfile.getId(), gameProfile.getName());
+ gameProfile.getProperties().values().forEach(property -> profile.setProperty(toBukkit(property)));
+ return profile;
+ }
+
+ public static Property asAuthlib(ProfileProperty property) {
+ return new Property(property.getName(), property.getValue(), property.getSignature());
+ }
+} +}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 8d0a9e8ca..7d26531d8 100644 index 8d0a9e8ca..f0ae65f08 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.util.CraftNamespacedKey; @@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.util.CraftNamespacedKey;
@ -138,7 +148,7 @@ index 8d0a9e8ca..7d26531d8 100644
+ } + }
+ +
+ public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) { + public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) {
+ return new com.destroystokyo.paper.profile.CraftGameProfile(uuid, name); + return new com.destroystokyo.paper.profile.CraftPlayerProfile(uuid, name);
+ } + }
// Paper end // Paper end
} }

View file

@ -6,15 +6,91 @@ Subject: [PATCH] Profile Lookup Events
Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from
profiles that had to be looked up. profiles that had to be looked up.
diff --git a/src/main/java/com/destroystokyo/paper/profile/WrappedGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/WrappedGameProfileRepository.java
new file mode 100644
index 000000000..950fa930d
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/profile/WrappedGameProfileRepository.java
@@ -0,0 +0,0 @@
+package com.destroystokyo.paper.profile;
+
+import com.destroystokyo.paper.event.profile.LookupProfileEvent;
+import com.destroystokyo.paper.event.profile.PreLookupProfileEvent;
+import com.google.common.collect.Sets;
+import com.mojang.authlib.Agent;
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.GameProfileRepository;
+import com.mojang.authlib.ProfileLookupCallback;
+import com.mojang.authlib.properties.Property;
+
+import javax.annotation.Nonnull;
+import java.util.Set;
+
+public class WrappedGameProfileRepository implements GameProfileRepository {
+
+ private final GameProfileRepository orig;
+ public WrappedGameProfileRepository(@Nonnull GameProfileRepository orig) {
+ this.orig = orig;
+ }
+
+ @Override
+ public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) {
+ Set<String> unfoundNames = Sets.newHashSet();
+ for (String name : names) {
+ PreLookupProfileEvent event = new PreLookupProfileEvent(name);
+ event.callEvent();
+ if (event.getUUID() != null) {
+ // Plugin provided UUI, we can skip network call.
+ GameProfile gameprofile = new GameProfile(event.getUUID(), name);
+ // We might even have properties!
+ Set<ProfileProperty> profileProperties = event.getProfileProperties();
+ if (!profileProperties.isEmpty()) {
+ for (ProfileProperty property : profileProperties) {
+ gameprofile.getProperties().put(property.getName(), CraftPlayerProfile.asAuthlib(property));
+ }
+ }
+ callback.onProfileLookupSucceeded(gameprofile);
+ } else {
+ unfoundNames.add(name);
+ }
+ }
+
+ // Some things were not found.... Proceed to look up.
+ if (!unfoundNames.isEmpty()) {
+ String[] namesArr = unfoundNames.toArray(new String[unfoundNames.size()]);
+ orig.findProfilesByNames(namesArr, agent, new PreProfileLookupCallback(callback));
+ }
+ }
+
+ private static class PreProfileLookupCallback implements ProfileLookupCallback {
+ private final ProfileLookupCallback callback;
+
+ PreProfileLookupCallback(ProfileLookupCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onProfileLookupSucceeded(GameProfile gameProfile) {
+ PlayerProfile from = CraftPlayerProfile.from(gameProfile);
+ new LookupProfileEvent(from).callEvent();
+ callback.onProfileLookupSucceeded(gameProfile);
+ }
+
+ @Override
+ public void onProfileLookupFailed(GameProfile gameProfile, Exception e) {
+ callback.onProfileLookupFailed(gameProfile, e);
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index e8bddc171..0e255861d 100644 index e8bddc171..6159cf4c0 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs @@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString());
MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService(); MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository(); GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository();
+ gameprofilerepository = com.destroystokyo.paper.event.profile.PreLookupProfileEvent.wrapProfileRepository(gameprofilerepository); // Paper + gameprofilerepository = new com.destroystokyo.paper.profile.WrappedGameProfileRepository(gameprofilerepository); // Paper
UserCache usercache = new UserCache(gameprofilerepository, new File(s1, MinecraftServer.a.getName())); UserCache usercache = new UserCache(gameprofilerepository, new File(s1, MinecraftServer.a.getName()));
final DedicatedServer dedicatedserver = new DedicatedServer(options, DataConverterRegistry.a(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache); final DedicatedServer dedicatedserver = new DedicatedServer(options, DataConverterRegistry.a(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache);