Skip to content

Instantly share code, notes, and snippets.

@Jofkos
Last active May 2, 2024 09:39
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Jofkos/d0c469528b032d820f42 to your computer and use it in GitHub Desktop.
Save Jofkos/d0c469528b032d820f42 to your computer and use it in GitHub Desktop.
UUIDFetcher
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import org.bukkit.craftbukkit.libs.com.google.gson.Gson;
import org.bukkit.craftbukkit.libs.com.google.gson.GsonBuilder;
import com.mojang.util.UUIDTypeAdapter;
public class UUIDFetcher {
/**
* Date when name changes were introduced
* @see UUIDFetcher#getUUIDAt(String, long)
*/
public static final long FEBRUARY_2015 = 1422748800000L;
private static Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
private static final String UUID_URL = "https://api.mojang.com/users/profiles/minecraft/%s?at=%d";
private static final String NAME_URL = "https://api.mojang.com/user/profile/%s";
private static Map<String, UUID> uuidCache = new HashMap<String, UUID>();
private static Map<UUID, String> nameCache = new HashMap<UUID, String>();
private static ExecutorService pool = Executors.newCachedThreadPool();
private String name;
private UUID id;
/**
* Fetches the uuid asynchronously and passes it to the consumer
*
* @param name The name
* @param action Do what you want to do with the uuid her
*/
public static void getUUID(String name, Consumer<UUID> action) {
pool.execute(() -> action.accept(getUUID(name)));
}
/**
* Fetches the uuid synchronously and returns it
*
* @param name The name
* @return The uuid
*/
public static UUID getUUID(String name) {
return getUUIDAt(name, System.currentTimeMillis());
}
/**
* Fetches the uuid synchronously for a specified name and time and passes the result to the consumer
*
* @param name The name
* @param timestamp Time when the player had this name in milliseconds
* @param action Do what you want to do with the uuid her
*/
public static void getUUIDAt(String name, long timestamp, Consumer<UUID> action) {
pool.execute(() -> action.accept(getUUIDAt(name, timestamp)));
}
/**
* Fetches the uuid synchronously for a specified name and time
*
* @param name The name
* @param timestamp Time when the player had this name in milliseconds
* @see UUIDFetcher#FEBRUARY_2015
*/
public static UUID getUUIDAt(String name, long timestamp) {
name = name.toLowerCase();
if (uuidCache.containsKey(name)) {
return uuidCache.get(name);
}
try {
HttpURLConnection connection = (HttpURLConnection) new URL(String.format(UUID_URL, name, timestamp/1000)).openConnection();
connection.setReadTimeout(5000);
UUIDFetcher data = gson.fromJson(new BufferedReader(new InputStreamReader(connection.getInputStream())), UUIDFetcher.class);
uuidCache.put(name, data.id);
nameCache.put(data.id, data.name);
return data.id;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Fetches the name asynchronously and passes it to the consumer
*
* @param uuid The uuid
* @param action Do what you want to do with the name her
*/
public static void getName(UUID uuid, Consumer<String> action) {
pool.execute(() -> action.accept(getName(uuid)));
}
/**
* Fetches the name synchronously and returns it
*
* @param uuid The uuid
* @return The name
*/
public static String getName(UUID uuid) {
if (nameCache.containsKey(uuid)) {
return nameCache.get(uuid);
}
try {
HttpURLConnection connection = (HttpURLConnection) new URL(String.format(NAME_URL, UUIDTypeAdapter.fromUUID(uuid))).openConnection();
connection.setReadTimeout(5000);
UUIDFetcher currentNameData = gson.fromJson(new BufferedReader(new InputStreamReader(connection.getInputStream())), UUIDFetcher.class);
uuidCache.put(currentNameData.name.toLowerCase(), uuid);
nameCache.put(uuid, currentNameData.name);
return currentNameData.name;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
@leNicDev
Copy link

leNicDev commented Dec 1, 2015

deinCraft approved :)

@ouihq
Copy link

ouihq commented Mar 1, 2021

What if i cant use UUIDTypeAdapter.create()?

@toohard2explain
Copy link

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.UUID;

public class UUIDTypeAdapter extends TypeAdapter<UUID> {
    public void write(JsonWriter out, UUID value) throws IOException {
        out.value(fromUUID(value));
    }

    public UUID read(JsonReader in) throws IOException {
        return fromString(in.nextString());
    }

    public static String fromUUID(UUID value) {
        return value.toString().replace("-", "");
    }

    public static UUID fromString(String input) {
        return UUID.fromString(input.replaceFirst(
                "(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
    }
}

@bestlinuxgamers
Copy link

Since Mojangs latest API change getName() does not work anymore.

java.io.FileNotFoundException: https://api.mojang.com/user/profiles/UUID/names
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1993)
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:224)
	at org.example.UUIDFetcher.getName(UUIDFetcher.java:122)

This patch fixes the error:

Index: UUIDFetcher.java
<+>UTF-8
===================================================================
diff --git a/UUIDFetcher.java b/UUIDFetcher.java
--- a/UUIDFetcher.java	(revision 0c598b95ee3f40c5bef2fc48497fc384fb35f4cc)
+++ b/UUIDFetcher.java	(revision 4a3142e46d96132da6f41ff6f21b49924006d142)
@@ -26,7 +26,7 @@
 	private static Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
 	
 	private static final String UUID_URL = "https://api.mojang.com/users/profiles/minecraft/%s?at=%d";
-	private static final String NAME_URL = "https://api.mojang.com/user/profiles/%s/names";
+	private static final String NAME_URL = "https://api.mojang.com/user/profile/%s";
 
 	private static Map<String, UUID> uuidCache = new HashMap<String, UUID>();
 	private static Map<UUID, String> nameCache = new HashMap<UUID, String>();
@@ -118,8 +118,7 @@
 		try {
 			HttpURLConnection connection = (HttpURLConnection) new URL(String.format(NAME_URL, UUIDTypeAdapter.fromUUID(uuid))).openConnection();
 			connection.setReadTimeout(5000);
-			UUIDFetcher[] nameHistory = gson.fromJson(new BufferedReader(new InputStreamReader(connection.getInputStream())), UUIDFetcher[].class);
-			UUIDFetcher currentNameData = nameHistory[nameHistory.length - 1];
+			UUIDFetcher currentNameData = gson.fromJson(new BufferedReader(new InputStreamReader(connection.getInputStream())), UUIDFetcher.class);
 
 			uuidCache.put(currentNameData.name.toLowerCase(), uuid);
 			nameCache.put(uuid, currentNameData.name);

@Jofkos
Copy link
Author

Jofkos commented Oct 9, 2022

Since Mojangs latest API change getName() does not work anymore.

java.io.FileNotFoundException: https://api.mojang.com/user/profiles/UUID/names
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1993)
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:224)
	at org.example.UUIDFetcher.getName(UUIDFetcher.java:122)

This patch fixes the error:

Thanks, @bestlinuxgamers, I updated it :)

@WafeCode
Copy link

at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1993)

@Jofkos Could you send me the entire class? because I couldn't apply the path!

@bestlinuxgamers
Copy link

at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1993)

@Jofkos Could you send me the entire class? because I couldn't apply the path!

The gist has already been updated. Just use the current version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment