1ebe37e5a3
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.
237 lines
7.8 KiB
Diff
237 lines
7.8 KiB
Diff
From e9962451b7d9b18132004f808364cb76fc3fe0cb Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Sat, 17 Jun 2017 16:30:44 -0400
|
|
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
|
|
profiles that had to be looked up.
|
|
|
|
diff --git a/pom.xml b/pom.xml
|
|
index 862910e0..c2922a7b 100644
|
|
--- a/pom.xml
|
|
+++ b/pom.xml
|
|
@@ -60,6 +60,13 @@
|
|
<!-- Trove Provided by CraftBukkit -->
|
|
<scope>provided</scope>
|
|
</dependency>
|
|
+ <!-- Paper - Add Authlib for Profile API -->
|
|
+ <dependency>
|
|
+ <groupId>com.mojang</groupId>
|
|
+ <artifactId>authlib</artifactId>
|
|
+ <version>1.5.25</version> <!-- keep in sync with major MC versions -->
|
|
+ <scope>compile</scope> <!-- expose to Plugins -->
|
|
+ </dependency>
|
|
<dependency>
|
|
<groupId>co.aikar</groupId>
|
|
<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
|
|
new file mode 100644
|
|
index 00000000..b46a1878
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java
|
|
@@ -0,0 +1,44 @@
|
|
+package com.destroystokyo.paper.event.profile;
|
|
+
|
|
+import com.mojang.authlib.GameProfile;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.event.Event;
|
|
+import org.bukkit.event.HandlerList;
|
|
+
|
|
+import javax.annotation.Nonnull;
|
|
+
|
|
+/**
|
|
+ * Allows a plugin to be notified anytime AFTER a Profile has been looked up from the Mojang API
|
|
+ *
|
|
+ * This is an opportunity to view the response and potentially cache things.
|
|
+ *
|
|
+ * No guarantees are made about thread execution context for this event. If you need to know, check
|
|
+ * event.isAsync()
|
|
+ */
|
|
+public class LookupProfileEvent extends Event {
|
|
+
|
|
+ private static final HandlerList handlers = new HandlerList();
|
|
+
|
|
+ private final GameProfile profile;
|
|
+
|
|
+ public LookupProfileEvent(@Nonnull GameProfile profile) {
|
|
+ super(!Bukkit.isPrimaryThread());
|
|
+ this.profile = profile;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The profile that was recently looked up. This profile can be mutated
|
|
+ */
|
|
+ @Nonnull
|
|
+ public GameProfile getProfile() {
|
|
+ return profile;
|
|
+ }
|
|
+
|
|
+ public HandlerList getHandlers() {
|
|
+ return handlers;
|
|
+ }
|
|
+
|
|
+ public static HandlerList getHandlerList() {
|
|
+ return handlers;
|
|
+ }
|
|
+}
|
|
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
|
|
index 00000000..16f43b0f
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
|
|
@@ -0,0 +1,152 @@
|
|
+package com.destroystokyo.paper.event.profile;
|
|
+
|
|
+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.PropertyMap;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.event.Event;
|
|
+import org.bukkit.event.HandlerList;
|
|
+
|
|
+import javax.annotation.Nonnull;
|
|
+import javax.annotation.Nullable;
|
|
+import java.util.Set;
|
|
+import java.util.UUID;
|
|
+
|
|
+/**
|
|
+ * Allows a plugin to intercept a Profile Lookup for a Profile by name
|
|
+ *
|
|
+ * At the point of event fire, the UUID and properties are unset.
|
|
+ *
|
|
+ * If a plugin sets the UUID, and optionally the properties, the API call to look up the profile may be skipped.
|
|
+ *
|
|
+ * No guarantees are made about thread execution context for this event. If you need to know, check
|
|
+ * event.isAsync()
|
|
+ */
|
|
+public class PreLookupProfileEvent extends Event {
|
|
+
|
|
+ private static final HandlerList handlers = new HandlerList();
|
|
+
|
|
+ private final String name;
|
|
+
|
|
+ private UUID uuid;
|
|
+ private PropertyMap properties = new PropertyMap();
|
|
+
|
|
+ public PreLookupProfileEvent(@Nonnull String name) {
|
|
+ super(!Bukkit.isPrimaryThread());
|
|
+ this.name = name;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Name of the player to look up a profile for
|
|
+ * @return
|
|
+ */
|
|
+ @Nonnull
|
|
+ public String getName() {
|
|
+ return name;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * The UUID of the profile if it has already been provided by a plugin
|
|
+ *
|
|
+ * If this value is left null by the completion of the event call, then the server will
|
|
+ * trigger a call to the Mojang API to look up the UUID (Network Request), and subsequently, fire a
|
|
+ * {@link LookupProfileEvent}
|
|
+ */
|
|
+ @Nullable
|
|
+ public UUID getUUID() {
|
|
+ return 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.
|
|
+ */
|
|
+ public void setUUID(@Nullable UUID uuid) {
|
|
+ this.uuid = uuid;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Get the properties for this profile
|
|
+ */
|
|
+ @Nonnull
|
|
+ public Multimap<String, Property> getProperties() {
|
|
+ return properties;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Completely replaces all Properties with the new provided properties
|
|
+ * @param properties
|
|
+ */
|
|
+ public void setProperties(Multimap<String, Property> properties) {
|
|
+ this.properties = new PropertyMap();
|
|
+ this.properties.putAll(properties);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Adds additional properties, without removing the original properties
|
|
+ * @param properties
|
|
+ */
|
|
+ public void addProperties(Multimap<String, Property> properties) {
|
|
+ this.properties.putAll(properties);
|
|
+ }
|
|
+
|
|
+ public HandlerList getHandlers() {
|
|
+ return handlers;
|
|
+ }
|
|
+
|
|
+ public static HandlerList getHandlerList() {
|
|
+ return handlers;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Wraps the Profile Repository so we can intercept all lookups
|
|
+ */
|
|
+ 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));
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ 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);
|
|
+ }
|
|
+ }
|
|
+}
|
|
--
|
|
2.13.0
|
|
|