From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 17 Jun 2017 17:00:32 -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/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
index 582c169c85ac66f1f9430f79042e4655f776c157..08fdb681a68e8be6e4062af0630957ce3e524806 100644
--- a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
@@ -1,11 +1,16 @@
 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.Environment;
+import com.mojang.authlib.GameProfile;
 import com.mojang.authlib.ProfileLookupCallback;
 import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
 import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
 
+import java.util.Set;
 public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
     public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService, Environment environment) {
         super(authenticationService, environment);
@@ -13,6 +18,50 @@ public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
 
     @Override
     public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) {
-        super.findProfilesByNames(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!
+                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()]);
+            super.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.asBukkitMirror(gameProfile);
+            new LookupProfileEvent(from).callEvent();
+            callback.onProfileLookupSucceeded(gameProfile);
+        }
+
+        @Override
+        public void onProfileLookupFailed(GameProfile gameProfile, Exception e) {
+            callback.onProfileLookupFailed(gameProfile, e);
+        }
     }
 }
