package com.mojang.authlib.yggdrasil; import com.mojang.authlib.Agent; import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.ProfileLookupCallback; import launcher.client.PlayerProfile; import launcher.helper.LogHelper; import launcher.helper.VerifyHelper; import launcher.request.uuid.BatchProfileByUsernameRequest; import java.util.Arrays; import java.util.UUID; public class YggdrasilGameProfileRepository implements GameProfileRepository { private static final long BUSY_WAIT_MS = VerifyHelper.verifyLong( Long.parseLong(System.getProperty("launcher.authlib.busyWait", Long.toString(100L))), VerifyHelper.L_NOT_NEGATIVE, "launcher.authlib.busyWait can't be < 0"); private static final long ERROR_BUSY_WAIT_MS = VerifyHelper.verifyLong( Long.parseLong(System.getProperty("launcher.authlib.errorBusyWait", Long.toString(500L))), VerifyHelper.L_NOT_NEGATIVE, "launcher.authlib.errorBusyWait can't be < 0"); public YggdrasilGameProfileRepository() { LogHelper.debug("Patched GameProfileRepository created"); } public YggdrasilGameProfileRepository(YggdrasilAuthenticationService authenticationService) { this(); } private static void busyWait(long ms) { try { Thread.sleep(ms); } catch (InterruptedException e) { LogHelper.error(e); } } @Override public void findProfilesByNames(String[] usernames, Agent agent, ProfileLookupCallback callback) { int offset = 0; while (offset < usernames.length) { String[] sliceUsernames = Arrays.copyOfRange(usernames, offset, Math.min(offset + BatchProfileByUsernameRequest.MAX_BATCH_SIZE, usernames.length)); offset += BatchProfileByUsernameRequest.MAX_BATCH_SIZE; // Batch Username-To-UUID request PlayerProfile[] sliceProfiles; try { sliceProfiles = new BatchProfileByUsernameRequest(sliceUsernames).request(); } catch (Throwable exc) { for (String username : sliceUsernames) { LogHelper.debug("Couldn't find profile '%s': %s", username, exc); callback.onProfileLookupFailed(new GameProfile((UUID) null, username), exc instanceof Exception ? (Exception) exc : new Exception(exc)); } // Busy wait, like in standard authlib busyWait(ERROR_BUSY_WAIT_MS); continue; } // Request succeeded! for (int i = 0; i < sliceProfiles.length; i++) { PlayerProfile pp = sliceProfiles[i]; if (pp == null) { String username = sliceUsernames[i]; LogHelper.debug("Couldn't find profile '%s'", username); callback.onProfileLookupFailed(new GameProfile((UUID) null, username), new ProfileNotFoundException("Server did not find the requested profile")); continue; } // Report as looked up LogHelper.debug("Successfully looked up profile '%s'", pp.username); callback.onProfileLookupSucceeded(YggdrasilMinecraftSessionService.toGameProfile(pp)); } // Busy wait, like in standard authlib busyWait(BUSY_WAIT_MS); } } }