|
18 | 18 | */ |
19 | 19 | package dev.noah.perplayerkit.commands; |
20 | 20 |
|
| 21 | +import com.squareup.okhttp.OkHttpClient; |
| 22 | +import com.squareup.okhttp.Request; |
| 23 | +import com.squareup.okhttp.Response; |
21 | 24 | import dev.noah.perplayerkit.util.BroadcastManager; |
22 | 25 | import net.kyori.adventure.text.Component; |
23 | 26 | import net.kyori.adventure.text.minimessage.MiniMessage; |
|
27 | 30 | import org.jetbrains.annotations.NotNull; |
28 | 31 | import org.jetbrains.annotations.Nullable; |
29 | 32 |
|
| 33 | +import java.io.IOException; |
| 34 | +import java.nio.charset.StandardCharsets; |
30 | 35 | import java.util.UUID; |
31 | 36 | import java.util.concurrent.CompletableFuture; |
32 | 37 |
|
@@ -63,14 +68,36 @@ public static CompletableFuture<UUID> resolvePlayerIdentifierAsync(String identi |
63 | 68 | return CompletableFuture.completedFuture(onlinePlayer.getUniqueId()); |
64 | 69 | } |
65 | 70 |
|
66 | | - // Search offline players asynchronously (this can be slow) |
| 71 | + // Look up UUID via Mojang API (avoids the very slow Bukkit.getOfflinePlayers() scan) |
67 | 72 | return CompletableFuture.supplyAsync(() -> { |
68 | | - for (OfflinePlayer offlinePlayer : Bukkit.getOfflinePlayers()) { |
69 | | - if (identifier.equalsIgnoreCase(offlinePlayer.getName())) { |
70 | | - return offlinePlayer.getUniqueId(); |
| 73 | + try { |
| 74 | + OkHttpClient client = new OkHttpClient(); |
| 75 | + Request request = new Request.Builder() |
| 76 | + .url("https://api.mojang.com/users/profiles/minecraft/" + identifier) |
| 77 | + .build(); |
| 78 | + try (Response response = client.newCall(request).execute()) { |
| 79 | + if (response.isSuccessful() && response.body() != null) { |
| 80 | + String body = response.body().string(); |
| 81 | + // Parse the "id" field: {"id":"<uuid-no-dashes>","name":"<name>"} |
| 82 | + int idStart = body.indexOf("\"id\":\"") + 6; |
| 83 | + int idEnd = body.indexOf("\"", idStart); |
| 84 | + if (idStart > 5 && idEnd > idStart) { |
| 85 | + String raw = body.substring(idStart, idEnd); |
| 86 | + // Insert dashes into the 32-char UUID string |
| 87 | + String formatted = raw.substring(0, 8) + "-" |
| 88 | + + raw.substring(8, 12) + "-" |
| 89 | + + raw.substring(12, 16) + "-" |
| 90 | + + raw.substring(16, 20) + "-" |
| 91 | + + raw.substring(20); |
| 92 | + return UUID.fromString(formatted); |
| 93 | + } |
| 94 | + } |
71 | 95 | } |
| 96 | + } catch (IOException ignored) { |
| 97 | + // Fall through to offline UUID computation |
72 | 98 | } |
73 | | - return null; |
| 99 | + // Fallback for offline/cracked-mode servers: compute deterministic offline UUID |
| 100 | + return UUID.nameUUIDFromBytes(("OfflinePlayer:" + identifier).getBytes(StandardCharsets.UTF_8)); |
74 | 101 | }); |
75 | 102 | } |
76 | 103 |
|
|
0 commit comments