2828import eu .kennytv .maintenance .core .proxy .runnable .SingleMaintenanceScheduleRunnable ;
2929import eu .kennytv .maintenance .core .proxy .util .ProfileLookup ;
3030import eu .kennytv .maintenance .core .runnable .MaintenanceRunnableBase ;
31+ import eu .kennytv .maintenance .core .util .RateLimitedException ;
3132import eu .kennytv .maintenance .core .util .SenderInfo ;
3233import eu .kennytv .maintenance .core .util .ServerType ;
3334import eu .kennytv .maintenance .core .util .Task ;
35+ import org .jetbrains .annotations .Blocking ;
3436import org .jetbrains .annotations .Nullable ;
3537
3638import java .io .IOException ;
3739import java .io .InputStream ;
3840import java .io .InputStreamReader ;
41+ import java .net .HttpURLConnection ;
3942import java .net .URL ;
40- import java .net . URLConnection ;
43+ import java .nio . charset . StandardCharsets ;
4144import java .util .ArrayList ;
4245import java .util .Collections ;
4346import java .util .HashMap ;
@@ -187,9 +190,66 @@ protected void kickPlayers() {
187190 kickPlayersFromProxy ();
188191 }
189192
193+ @ Blocking
194+ @ Nullable
190195 protected ProfileLookup doUUIDLookup (final String name ) throws IOException {
196+ ProfileLookup profileLookup ;
197+ try {
198+ profileLookup = doUUIDLookupMojangAPI (name );
199+ } catch (RateLimitedException e ) {
200+ // Use fallback API if rate limit is reached
201+ profileLookup = doUUIDLookupAshconAPI (name );
202+ }
203+
204+ if (settingsProxy .isFallbackToOfflineUUID () && profileLookup == null ) {
205+ // Use offline uuid
206+ return new ProfileLookup (UUID .nameUUIDFromBytes (("OfflinePlayer:" + name ).getBytes (StandardCharsets .UTF_8 )), name );
207+ }
208+
209+ return profileLookup ;
210+ }
211+
212+ /**
213+ * Official Mojang API
214+ */
215+ @ Nullable
216+ private ProfileLookup doUUIDLookupMojangAPI (final String name ) throws IOException {
217+ final URL url = new URL ("https://api.mojang.com/users/profiles/minecraft/" + name );
218+ final HttpURLConnection connection = (HttpURLConnection ) url .openConnection ();
219+ connection .setRequestMethod ("GET" );
220+
221+ int status = connection .getResponseCode ();
222+ if (status == 429 ) {
223+ throw new RateLimitedException ();
224+ }
225+ if (status == 404 ) {
226+ // Return null if profile not found
227+ return null ;
228+ }
229+
230+ try (final InputStream in = connection .getInputStream ()) {
231+ final String output = CharStreams .toString (new InputStreamReader (in ));
232+ final JsonObject json = GSON .fromJson (output , JsonObject .class );
233+
234+ final UUID uuid = fromStringUUIDWithoutDashes (json .getAsJsonPrimitive ("id" ).getAsString ());
235+ final String username = json .getAsJsonPrimitive ("name" ).getAsString ();
236+ return new ProfileLookup (uuid , username );
237+ }
238+ }
239+
240+ /**
241+ * Fallback API (Ashcon API)
242+ */
243+ @ Nullable
244+ private ProfileLookup doUUIDLookupAshconAPI (final String name ) throws IOException {
191245 final URL url = new URL ("https://api.ashcon.app/mojang/v2/user/" + name );
192- final URLConnection connection = url .openConnection ();
246+ final HttpURLConnection connection = (HttpURLConnection ) url .openConnection ();
247+
248+ if (connection .getResponseCode () == 403 ) {
249+ // Return null if profile not found
250+ return null ;
251+ }
252+
193253 try (final InputStream in = connection .getInputStream ()) {
194254 final String output = CharStreams .toString (new InputStreamReader (in ));
195255 final JsonObject json = GSON .fromJson (output , JsonObject .class );
@@ -200,6 +260,14 @@ protected ProfileLookup doUUIDLookup(final String name) throws IOException {
200260 }
201261 }
202262
263+ private UUID fromStringUUIDWithoutDashes (String undashedUUID ) {
264+ return UUID .fromString (
265+ undashedUUID .substring (0 , 8 ) + "-" + undashedUUID .substring (8 , 12 ) + "-" +
266+ undashedUUID .substring (12 , 16 ) + "-" + undashedUUID .substring (16 , 20 ) + "-" +
267+ undashedUUID .substring (20 , 32 )
268+ );
269+ }
270+
203271 public SettingsProxy getSettingsProxy () {
204272 return settingsProxy ;
205273 }
0 commit comments