Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package com.legacyminecraft.poseidon.util;
2
3import com.google.common.collect.ImmutableList;
4import com.legacyminecraft.poseidon.PoseidonConfig;
5import org.json.simple.JSONArray;
6import org.json.simple.JSONObject;
7import org.json.simple.parser.JSONParser;
8
9import java.io.InputStreamReader;
10import java.io.OutputStream;
11import java.net.HttpURLConnection;
12import java.net.URL;
13import java.nio.ByteBuffer;
14import java.util.*;
15import java.util.concurrent.Callable;
16
17public class UUIDFetcher implements Callable<Map<String, UUID>> {
18 private static final double PROFILES_PER_REQUEST = 100;
19 private static final String PROFILE_URL = PoseidonConfig.getInstance().getString("settings.uuid-fetcher.post.value", "https://api.minecraftservices.com/minecraft/profile/lookup/bulk/byname");
20 private final JSONParser jsonParser = new JSONParser();
21 private final List<String> names;
22 private final boolean rateLimiting;
23
24 public UUIDFetcher(List<String> names, boolean rateLimiting) {
25 this.names = ImmutableList.copyOf(names);
26 this.rateLimiting = rateLimiting;
27 }
28
29 public UUIDFetcher(List<String> names) {
30 this(names, true);
31 }
32
33 public Map<String, UUID> call() throws Exception {
34 Map<String, UUID> uuidMap = new HashMap<String, UUID>();
35 int requests = (int) Math.ceil(names.size() / PROFILES_PER_REQUEST);
36 for (int i = 0; i < requests; i++) {
37 HttpURLConnection connection = createConnection();
38 String body = JSONArray.toJSONString(names.subList(i * 100, Math.min((i + 1) * 100, names.size())));
39 writeBody(connection, body);
40 JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream()));
41 for (Object profile : array) {
42 JSONObject jsonProfile = (JSONObject) profile;
43 String id = (String) jsonProfile.get("id");
44 String name = (String) jsonProfile.get("name");
45 UUID uuid = UUIDFetcher.getUUID(id);
46 uuidMap.put(name, uuid);
47 }
48 if (rateLimiting && i != requests - 1) {
49 Thread.sleep(100L);
50 }
51 }
52 return uuidMap;
53 }
54
55 private static void writeBody(HttpURLConnection connection, String body) throws Exception {
56 OutputStream stream = connection.getOutputStream();
57 stream.write(body.getBytes());
58 stream.flush();
59 stream.close();
60 }
61
62 private static HttpURLConnection createConnection() throws Exception {
63 URL url = new URL(PROFILE_URL);
64 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
65 connection.setRequestMethod("POST");
66 connection.setRequestProperty("Content-Type", "application/json");
67 connection.setUseCaches(false);
68 connection.setDoInput(true);
69 connection.setDoOutput(true);
70 return connection;
71 }
72
73 private static UUID getUUID(String id) {
74 return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32));
75 }
76
77 public static byte[] toBytes(UUID uuid) {
78 ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
79 byteBuffer.putLong(uuid.getMostSignificantBits());
80 byteBuffer.putLong(uuid.getLeastSignificantBits());
81 return byteBuffer.array();
82 }
83
84 public static UUID fromBytes(byte[] array) {
85 if (array.length != 16) {
86 throw new IllegalArgumentException("Illegal byte array length: " + array.length);
87 }
88 ByteBuffer byteBuffer = ByteBuffer.wrap(array);
89 long mostSignificant = byteBuffer.getLong();
90 long leastSignificant = byteBuffer.getLong();
91 return new UUID(mostSignificant, leastSignificant);
92 }
93
94 public static UUID getUUIDOf(String name) throws Exception {
95 return new UUIDFetcher(Arrays.asList(name)).call().get(name);
96 }
97}