Skip to content

Commit 71d95e8

Browse files
committed
Changes to SkullAPI, added caching for urls/base64 skulls
1 parent cf1d72b commit 71d95e8

File tree

2 files changed

+71
-351
lines changed

2 files changed

+71
-351
lines changed

SimpleAPI/src/main/java/com/bencodez/simpleapi/skull/SkullCache.java

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ public class SkullCache {
3333
* accessed.
3434
*/
3535
private static final HashMap<UUID, ItemStack> skullMap = new HashMap<>();
36+
private static final HashMap<String, ItemStack> skullBase64Map = new HashMap<>();
37+
private static final HashMap<String, Long> timeBase64Map = new HashMap<>();
38+
private static final HashMap<String, ItemStack> skullURLMap = new HashMap<>();
39+
private static final HashMap<String, Long> timeURLMap = new HashMap<>();
3640
private static final HashMap<UUID, Long> timeMap = new HashMap<>();
3741

3842
/**
@@ -41,10 +45,20 @@ public class SkullCache {
4145
* @param uuid The player's uuid.
4246
*/
4347
public static void cacheSkull(UUID uuid, String name) {
44-
skullMap.put(uuid, skullFromUuid(uuid, name));
48+
skullMap.put(uuid, itemWithUuid(uuid, name));
4549
timeMap.put(uuid, System.currentTimeMillis());
4650
}
4751

52+
public static void cacheSkullBase64(String base64) {
53+
skullBase64Map.put(base64, itemWithBase64(base64));
54+
timeBase64Map.put(base64, System.currentTimeMillis());
55+
}
56+
57+
public static void cacheSkullURL(String url) {
58+
skullURLMap.put(url, itemWithURL(url));
59+
timeURLMap.put(url, System.currentTimeMillis());
60+
}
61+
4862
/**
4963
* Cache a skull from an offline player.
5064
*
@@ -73,7 +87,7 @@ public static void cacheSkulls(HashMap<UUID, String> uuids) {
7387
new Thread(() -> {
7488
long start = System.currentTimeMillis();
7589
for (Entry<UUID, String> entry : uuids.entrySet()) {
76-
skullMap.put(entry.getKey(), skullFromUuid(entry.getKey(), entry.getValue()));
90+
skullMap.put(entry.getKey(), itemWithUuid(entry.getKey(), entry.getValue()));
7791
timeMap.put(entry.getKey(), System.currentTimeMillis());
7892
}
7993
// Generate an inventory off the rip to try to fix the hashmap
@@ -128,7 +142,7 @@ public static ItemStack getSkull(UUID uuid, String name) {
128142
timeMap.put(uuid, System.currentTimeMillis());
129143
ItemStack skull = skullMap.get(uuid);
130144
if (skull == null) {
131-
skull = skullFromUuid(uuid, name);
145+
skull = itemWithUuid(uuid, name);
132146
cacheSkull(uuid, name);
133147
}
134148
return skull;
@@ -160,6 +174,26 @@ public static ItemStack getSkull(Player player) {
160174
return getSkull(player.getUniqueId(), player.getName());
161175
}
162176

177+
public static ItemStack getSkullBase64(String base64) {
178+
timeBase64Map.put(base64, System.currentTimeMillis());
179+
ItemStack skull = skullBase64Map.get(base64);
180+
if (skull == null) {
181+
skull = itemWithBase64(base64);
182+
cacheSkullBase64(base64);
183+
}
184+
return skull;
185+
}
186+
187+
public static ItemStack getSkullURL(String url) {
188+
timeURLMap.put(url, System.currentTimeMillis());
189+
ItemStack skull = skullURLMap.get(url);
190+
if (skull == null) {
191+
skull = itemWithURL(url);
192+
cacheSkullURL(url);
193+
}
194+
return skull;
195+
}
196+
163197
/**
164198
* Get an array of player skulls from uuids.
165199
*
@@ -227,30 +261,6 @@ public static void flushWeek() {
227261
flush(604800000);
228262
}
229263

230-
/**
231-
* Creates a new player head item stack.
232-
*
233-
* @return Player head.
234-
*/
235-
public static ItemStack createSkull() {
236-
return new ItemStack(Material.PLAYER_HEAD);
237-
}
238-
239-
/**
240-
* Creates a player skull item with the skin based on a player's UUID.
241-
*
242-
* @param id The player's UUID.
243-
* @return The head of the player.
244-
*/
245-
public static ItemStack skullFromUuid(UUID id, String name) {
246-
try {
247-
return itemWithUuid(createSkull(), id, name);
248-
} catch (Exception exception) {
249-
exception.printStackTrace();
250-
}
251-
return null;
252-
}
253-
254264
@SuppressWarnings("deprecation")
255265
static private JsonParser parser = new JsonParser();
256266
static private String API_PROFILE_LINK = "https://sessionserver.mojang.com/session/minecraft/profile/";
@@ -304,15 +314,47 @@ public static ItemStack getSkull(String url, UUID uuid) {
304314
return skull;
305315
}
306316

317+
public static ItemStack getSkull(String url) {
318+
ItemStack skull = new ItemStack(Material.PLAYER_HEAD);
319+
if (url == null || url.isEmpty())
320+
return skull;
321+
SkullMeta skullMeta = (SkullMeta) skull.getItemMeta();
322+
PlayerProfile profile = Bukkit.getServer().createPlayerProfile(UUID.randomUUID());
323+
try {
324+
profile.getTextures().setSkin(new URL(url));
325+
} catch (MalformedURLException e) {
326+
e.printStackTrace();
327+
}
328+
skullMeta.setOwnerProfile(profile);
329+
skull.setItemMeta(skullMeta);
330+
return skull;
331+
}
332+
333+
public static String getUrlFromBase64(String base64) {
334+
String decoded = new String(Base64.getDecoder().decode(base64));
335+
// We simply remove the "beginning" and "ending" part of the JSON, so we're left
336+
// with only the URL. You could use a proper
337+
// JSON parser for this, but that's not worth it. The String will always start
338+
// exactly with this stuff anyway
339+
return decoded.substring("{\"textures\":{\"SKIN\":{\"url\":\"".length(), decoded.length() - "\"}}}".length());
340+
}
341+
342+
public static ItemStack itemWithBase64(String base64) {
343+
return getSkull(getUrlFromBase64(base64));
344+
}
345+
346+
public static ItemStack itemWithURL(String url) {
347+
return getSkull(url);
348+
}
349+
307350
/**
308351
* Modifies a skull to use the skin of the player with a given uuid.
309352
*
310353
* @param item The item to apply the name to. Must be a player skull.
311354
* @param id The player's uuid.
312355
* @return The head of the player.
313356
*/
314-
public static ItemStack itemWithUuid(ItemStack item, UUID id, String playerName) throws Exception {
315-
notNull(item, "item");
357+
public static ItemStack itemWithUuid(UUID id, String playerName) {
316358
notNull(id, "id");
317359

318360
return getSkull(getSkinUrl(id.toString()), id);

0 commit comments

Comments
 (0)