From 4ea2fda60f12c175ca011f0cb14fbcbeaafebddf Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thethinkofdeath@gmail.com>
Date: Sun, 20 Apr 2014 13:18:55 +0100
Subject: [PATCH] Convert player skulls async


diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java
index 748f00a..255e0de 100644
--- a/src/main/java/net/minecraft/server/TileEntitySkull.java
+++ b/src/main/java/net/minecraft/server/TileEntitySkull.java
@@ -6,11 +6,25 @@ import net.minecraft.util.com.google.common.collect.Iterables;
 import net.minecraft.util.com.mojang.authlib.GameProfile;
 import net.minecraft.util.com.mojang.authlib.properties.Property;
 
+// Spigot start
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import net.minecraft.util.com.mojang.authlib.Agent;
+// Spigot end
+
 public class TileEntitySkull extends TileEntity {
 
     private int a;
     private int i;
     private GameProfile j = null;
+    // Spigot start
+    private static final Executor executor = Executors.newFixedThreadPool(3,
+            new ThreadFactoryBuilder()
+                    .setNameFormat("Head Conversion Thread - %1$d")
+                    .build()
+    );
+    // Spigot end
 
     public TileEntitySkull() {}
 
@@ -65,18 +79,53 @@ public class TileEntitySkull extends TileEntity {
     private void d() {
         if (this.j != null && !UtilColor.b(this.j.getName())) {
             if (!this.j.isComplete() || !this.j.getProperties().containsKey("textures")) {
-                GameProfile gameprofile = MinecraftServer.getServer().getUserCache().a(this.j.getName());
-
-                if (gameprofile != null) {
-                    Property property = (Property) Iterables.getFirst(gameprofile.getProperties().get("textures"), null);
-
-                    if (property == null) {
-                        gameprofile = MinecraftServer.getServer().av().fillProfileProperties(gameprofile, true);
+                // Spigot start - Handle async
+                final String name = this.j.getName();
+                setSkullType( 0 ); // Work around a client bug
+                executor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        GameProfile[] profiles = new GameProfile[1];
+                        GameProfileLookup gameProfileLookup = new GameProfileLookup(profiles);
+
+                        MinecraftServer.getServer().getGameProfileRepository().findProfilesByNames(new String[] { name }, Agent.MINECRAFT, gameProfileLookup);
+                        if (!MinecraftServer.getServer().getOnlineMode() && profiles[0] == null) {
+                            UUID uuid = EntityHuman.a(new GameProfile(null, name));
+                            GameProfile profile = new GameProfile(uuid, name);
+
+                            gameProfileLookup.onProfileLookupSucceeded(profile);
+                        }
+
+                        GameProfile profile = profiles[0];
+                        if (profile != null) {
+                            Property property = Iterables.getFirst(profile.getProperties().get("textures"), null);
+
+                            if (property == null) {
+                                profile = MinecraftServer.getServer().av().fillProfileProperties(profile, true);
+                            }
+
+                            final GameProfile finalProfile = profile;
+                            MinecraftServer.getServer().processQueue.add(new Runnable() {
+                                @Override
+                                public void run() {
+                                    a = 3;
+                                    j = finalProfile;
+                                    world.notify( x, y, z );
+                                }
+                            });
+                        } else {
+                            MinecraftServer.getServer().processQueue.add(new Runnable() {
+                                @Override
+                                public void run() {
+                                    a = 3;
+                                    j = new GameProfile( null, name );
+                                    world.notify( x, y, z );
+                                }
+                            });
+                        }
                     }
-
-                    this.j = gameprofile;
-                    this.update();
-                }
+                });
+                // Spigot end
             }
         }
     }
-- 
1.9.1