diff --git a/Xplat/src/main/java/vazkii/botania/data/UuidNameProvider.java b/Xplat/src/main/java/vazkii/botania/data/UuidNameProvider.java index d246cfbdab..52e8c250af 100644 --- a/Xplat/src/main/java/vazkii/botania/data/UuidNameProvider.java +++ b/Xplat/src/main/java/vazkii/botania/data/UuidNameProvider.java @@ -15,11 +15,15 @@ public class UuidNameProvider { private static final Map cache = new ConcurrentHashMap<>(); + private static final Map failureTimes = new ConcurrentHashMap<>(); private static final Duration CACHE_DURATION = Duration.ofMinutes(15); + private static final int MAX_FAILURES = 5; public static String getPlayerNameFromUUID(String uuid) { CacheEntry entry = cache.get(uuid); - if (entry != null && !entry.isExpired()) { + boolean isCacheExpired = entry == null || entry.isExpired(); + + if (!isCacheExpired) { return entry.name; } @@ -38,17 +42,45 @@ public static String getPlayerNameFromUUID(String uuid) { in.close(); JsonObject jsonObject = JsonParser.parseString(content.toString()).getAsJsonObject(); - String name = jsonObject.get("name").getAsString(); + if (jsonObject.has("name")) { + String name = jsonObject.get("name").getAsString(); - cache.put(uuid, new CacheEntry(name)); + cache.put(uuid, new CacheEntry(name)); + failureTimes.remove(uuid); // Reset failure count on success - return name; + return name; + } else { + recordFailureTime(uuid); + FailureEntry failureEntry = failureTimes.getOrDefault(uuid, new FailureEntry()); + if (failureEntry.failures >= MAX_FAILURES) { + if (isCacheExpired) { + cache.remove(uuid); + } + return uuid; + } + return null; + } } catch (Exception e) { e.printStackTrace(); + recordFailureTime(uuid); + + FailureEntry failureEntry = failureTimes.getOrDefault(uuid, new FailureEntry()); + if (failureEntry.failures >= MAX_FAILURES) { + if (isCacheExpired) { + cache.remove(uuid); + } + return uuid; + } return null; } } + private static void recordFailureTime(String uuid) { + FailureEntry failureEntry = failureTimes.computeIfAbsent(uuid, k -> new FailureEntry()); + failureEntry.failures++; + failureEntry.lastFailureTime = Instant.now(); + } + private static class CacheEntry { final String name; final Instant creationTime; @@ -62,4 +94,9 @@ boolean isExpired() { return Instant.now().isAfter(creationTime.plus(CACHE_DURATION)); } } + + private static class FailureEntry { + int failures = 0; + Instant lastFailureTime = Instant.now(); + } }