Skip to content

Commit

Permalink
Better UUID/skin cache behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Aug 9, 2014
1 parent b9e3172 commit eeaedf2
Showing 1 changed file with 52 additions and 43 deletions.
95 changes: 52 additions & 43 deletions src/main/java/net/citizensnpcs/npc/entity/HumanController.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public HumanController() {
super();
if (SKIN_THREAD == null) {
Bukkit.getScheduler().runTaskTimerAsynchronously(CitizensAPI.getPlugin(), SKIN_THREAD = new SkinThread(),
10, 100);
10, 10);
}
}

Expand Down Expand Up @@ -96,9 +96,6 @@ private void updateSkin(final NPC npc, final WorldServer nmsWorld, GameProfile p
ChatColor.stripColor(npc.data().<String> get(CACHED_SKIN_UUID_NAME_METADATA)))) {
skinUUID = npc.data().get(CACHED_SKIN_UUID_METADATA);
}
if (UUID_CACHE.containsKey(skinUUID)) {
skinUUID = UUID_CACHE.get(skinUUID);
}
Property cached = TEXTURE_CACHE.get(skinUUID);
if (cached != null) {
profile.getProperties().put("textures", cached);
Expand All @@ -125,8 +122,8 @@ public SkinFetcher(Callable<String> uuid, MinecraftSessionService repo, NPC npc)
private GameProfile fillProfileProperties(YggdrasilAuthenticationService auth, GameProfile profile,
boolean requireSecure) throws Exception {
URL url = HttpAuthenticationService.constantURL(new StringBuilder()
.append("https://sessionserver.mojang.com/session/minecraft/profile/")
.append(UUIDTypeAdapter.fromUUID(profile.getId())).toString());
.append("https://sessionserver.mojang.com/session/minecraft/profile/")
.append(UUIDTypeAdapter.fromUUID(profile.getId())).toString());
url = HttpAuthenticationService.concatenateURL(url,
new StringBuilder().append("unsigned=").append(!requireSecure).toString());
MinecraftProfilePropertiesResponse response = (MinecraftProfilePropertiesResponse) MAKE_REQUEST.invoke(
Expand All @@ -149,33 +146,40 @@ public void run() {
return;
}
GameProfile skinProfile = null;
try {
skinProfile = fillProfileProperties(
((YggdrasilMinecraftSessionService) repo).getAuthenticationService(),
new GameProfile(UUID.fromString(realUUID), ""), true);
} catch (Exception e) {
if (e.getMessage() != null && e.getMessage().contains("too many requests")) {
SKIN_THREAD.addRunnable(this);
SKIN_THREAD.delay();
Property cached = TEXTURE_CACHE.get(realUUID);
if (cached != null) {
skinProfile = new GameProfile(UUID.fromString(realUUID), "");
skinProfile.getProperties().put("textures", cached);
} else {
try {
skinProfile = fillProfileProperties(
((YggdrasilMinecraftSessionService) repo).getAuthenticationService(),
new GameProfile(UUID.fromString(realUUID), ""), true);
} catch (Exception e) {
if (e.getMessage() != null && e.getMessage().contains("too many requests")) {
SKIN_THREAD.addRunnable(this);
SKIN_THREAD.delay();
}
return;
}
return;
}
if (skinProfile == null || !skinProfile.getProperties().containsKey("textures"))
return;
Property textures = Iterables.getFirst(skinProfile.getProperties().get("textures"), null);
if (textures.getValue() != null && textures.getSignature() != null) {

if (skinProfile == null || !skinProfile.getProperties().containsKey("textures"))
return;
Property textures = Iterables.getFirst(skinProfile.getProperties().get("textures"), null);
if (textures.getValue() == null || textures.getSignature() == null)
return;
TEXTURE_CACHE.put(realUUID, new Property("textures", textures.getValue(), textures.getSignature()));
Bukkit.getScheduler().callSyncMethod(CitizensAPI.getPlugin(), new Callable<Void>() {
@Override
public Void call() {
if (npc.isSpawned()) {
npc.despawn(DespawnReason.PENDING_RESPAWN);
npc.spawn(npc.getStoredLocation());
}
return null;
}
});
}
Bukkit.getScheduler().callSyncMethod(CitizensAPI.getPlugin(), new Callable<Void>() {
@Override
public Void call() {
if (npc.isSpawned()) {
npc.despawn(DespawnReason.PENDING_RESPAWN);
npc.spawn(npc.getStoredLocation());
}
return null;
}
});
}
}

Expand All @@ -188,7 +192,8 @@ public void addRunnable(Runnable r) {
}

public void delay() {
delay = 12;
delay = 120; // need to wait a minute before Mojang accepts API
// calls again
}

@Override
Expand All @@ -208,7 +213,7 @@ public void run() {

public static class UUIDFetcher implements Callable<String> {
private final NPC npc;
private final String reportedUUID;
private String reportedUUID;

public UUIDFetcher(String reportedUUID, NPC npc) {
this.reportedUUID = reportedUUID;
Expand All @@ -217,25 +222,29 @@ public UUIDFetcher(String reportedUUID, NPC npc) {

@Override
public String call() throws Exception {
String skinUUID = UUID_CACHE.get(reportedUUID);
if (skinUUID != null) {
reportedUUID = skinUUID;
}
if (reportedUUID.contains("-")) {
return reportedUUID;
}
final GameProfileRepository repo = ((CraftServer) Bukkit.getServer()).getServer()
.getGameProfileRepository();
repo.findProfilesByNames(new String[] { ChatColor.stripColor(reportedUUID) }, Agent.MINECRAFT,
new ProfileLookupCallback() {
@Override
public void onProfileLookupFailed(GameProfile arg0, Exception arg1) {
throw new RuntimeException(arg1);
}
@Override
public void onProfileLookupFailed(GameProfile arg0, Exception arg1) {
throw new RuntimeException(arg1);
}

@Override
public void onProfileLookupSucceeded(final GameProfile profile) {
UUID_CACHE.put(reportedUUID, profile.getId().toString());
npc.data().setPersistent(CACHED_SKIN_UUID_METADATA, profile.getId().toString());
npc.data().setPersistent(CACHED_SKIN_UUID_NAME_METADATA, profile.getName());
}
});
@Override
public void onProfileLookupSucceeded(final GameProfile profile) {
UUID_CACHE.put(reportedUUID, profile.getId().toString());
npc.data().setPersistent(CACHED_SKIN_UUID_METADATA, profile.getId().toString());
npc.data().setPersistent(CACHED_SKIN_UUID_NAME_METADATA, profile.getName());
}
});
return npc.data().get(CACHED_SKIN_UUID_METADATA, reportedUUID);
}
}
Expand Down

0 comments on commit eeaedf2

Please sign in to comment.