From 630eae7862fbbd994c00665b206f7cc87970bdfd Mon Sep 17 00:00:00 2001 From: ZeoNight Date: Fri, 20 May 2022 00:41:44 +0300 Subject: [PATCH] fix mojang auth --- .../authlib/login/altening/AlteningAuth.java | 2 +- .../authlib/login/mojang/AuthResponse.java | 143 ++++++++++++++++++ .../login/mojang/MinecraftAuthenticator.java | 76 ++++++---- .../authlib/login/mojang/MinecraftToken.java | 16 +- .../feature/gui/screen/AltManagerScreen.java | 2 +- 5 files changed, 206 insertions(+), 33 deletions(-) create mode 100644 src/main/java/me/x150/authlib/login/mojang/AuthResponse.java diff --git a/src/main/java/me/x150/authlib/login/altening/AlteningAuth.java b/src/main/java/me/x150/authlib/login/altening/AlteningAuth.java index a042acb..bbdafc8 100644 --- a/src/main/java/me/x150/authlib/login/altening/AlteningAuth.java +++ b/src/main/java/me/x150/authlib/login/altening/AlteningAuth.java @@ -54,7 +54,7 @@ public class AlteningAuth { yggdrasilUserAuthentication.logIn(); ((IMinecraftClientAccessor) ShadowMain.client).setSession(new Session(yggdrasilUserAuthentication.getSelectedProfile().getName(), yggdrasilUserAuthentication.getSelectedProfile().getId().toString(), yggdrasilUserAuthentication.getAuthenticatedToken(), Optional.empty(), Optional.empty(), Session.AccountType.MOJANG)); this.username = yggdrasilUserAuthentication.getSelectedProfile().getName(); - return new MinecraftToken(yggdrasilUserAuthentication.getAuthenticatedToken(),username); + return new MinecraftToken(yggdrasilUserAuthentication.getAuthenticatedToken(),username,yggdrasilUserAuthentication.getSelectedProfile().getId()); } catch (AuthenticationException authenticationException) { return null; diff --git a/src/main/java/me/x150/authlib/login/mojang/AuthResponse.java b/src/main/java/me/x150/authlib/login/mojang/AuthResponse.java new file mode 100644 index 0000000..3b0acbe --- /dev/null +++ b/src/main/java/me/x150/authlib/login/mojang/AuthResponse.java @@ -0,0 +1,143 @@ +package me.x150.authlib.login.mojang; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class AuthResponse { + public class User { + + @SerializedName("id") + @Expose + private String id; + @SerializedName("username") + @Expose + private String username; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + } + public class SelectedProfile { + + @SerializedName("name") + @Expose + private String name; + @SerializedName("id") + @Expose + private String id; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + } + @SerializedName("user") + @Expose + private User user; + @SerializedName("clientToken") + @Expose + private String clientToken; + @SerializedName("accessToken") + @Expose + private String accessToken; + @SerializedName("selectedProfile") + @Expose + private SelectedProfile selectedProfile; + @SerializedName("availableProfiles") + @Expose + private List availableProfiles = null; + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public String getClientToken() { + return clientToken; + } + + public void setClientToken(String clientToken) { + this.clientToken = clientToken; + } + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public SelectedProfile getSelectedProfile() { + return selectedProfile; + } + + public void setSelectedProfile(SelectedProfile selectedProfile) { + this.selectedProfile = selectedProfile; + } + + public List getAvailableProfiles() { + return availableProfiles; + } + + public void setAvailableProfiles(List availableProfiles) { + this.availableProfiles = availableProfiles; + } + public class AvailableProfile { + + @SerializedName("name") + @Expose + private String name; + @SerializedName("id") + @Expose + private String id; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + } + +} diff --git a/src/main/java/me/x150/authlib/login/mojang/MinecraftAuthenticator.java b/src/main/java/me/x150/authlib/login/mojang/MinecraftAuthenticator.java index c28eb95..06f4e01 100644 --- a/src/main/java/me/x150/authlib/login/mojang/MinecraftAuthenticator.java +++ b/src/main/java/me/x150/authlib/login/mojang/MinecraftAuthenticator.java @@ -1,29 +1,24 @@ package me.x150.authlib.login.mojang; +import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; + +import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.List; import java.util.UUID; -import java.util.stream.Collectors; import me.x150.authlib.exception.AuthFailureException; import me.x150.authlib.login.altening.AlteningAuth; import me.x150.authlib.login.microsoft.MicrosoftAuthenticator; import me.x150.authlib.login.microsoft.XboxToken; -import me.x150.authlib.login.mojang.MinecraftToken; import me.x150.authlib.login.mojang.profile.MinecraftProfile; -import me.x150.authlib.login.mojang.profile.MinecraftProfileCape; -import me.x150.authlib.login.mojang.profile.MinecraftProfileSkin; import me.x150.authlib.struct.Authenticator; - public class MinecraftAuthenticator extends Authenticator { protected final MicrosoftAuthenticator microsoftAuthenticator = new MicrosoftAuthenticator(); @@ -44,13 +39,14 @@ public class MinecraftAuthenticator extends Authenticator { request.add("agent", agent); request.addProperty("username", email); request.addProperty("password", password); - request.addProperty("clientToken",""); - request.addProperty("requestUser", true); + request.addProperty("requestUser", false); String requestBody = request.toString(); + httpURLConnection.setFixedLengthStreamingMode(requestBody.length()); httpURLConnection.setRequestProperty("Content-Type", "application/json"); - httpURLConnection.setRequestProperty("Host", "authserver.mojang.com"); + // httpURLConnection.setRequestProperty("Host", "authserver.mojang.com"); httpURLConnection.connect(); + OutputStream outputStream = httpURLConnection.getOutputStream(); try { @@ -70,9 +66,9 @@ public class MinecraftAuthenticator extends Authenticator { if (outputStream != null) { outputStream.close(); } - JsonObject jsonObject = this.parseResponseData(httpURLConnection); - return new MinecraftToken(jsonObject.get("accessToken").getAsString(), ((JsonObject)jsonObject.get("selectedProfile")).get("name").getAsString()); + + return new MinecraftToken(jsonObject.get("accessToken").getAsString(), jsonObject.get("selectedProfile").getAsJsonObject().get("name").getAsString(),generateUUID(jsonObject.get("selectedProfile").getAsJsonObject().get("id").getAsString())); } catch (IOException var14) { throw new AuthFailureException(String.format("Authentication error. Request could not be made! Cause: '%s'", var14.getMessage())); } @@ -115,7 +111,7 @@ public class MinecraftAuthenticator extends Authenticator { } JsonObject jsonObject = this.microsoftAuthenticator.parseResponseData(httpURLConnection); - return new MinecraftToken(jsonObject.get("access_token").getAsString(), jsonObject.get("username").getAsString()); + return new MinecraftToken(jsonObject.get("access_token").getAsString(), jsonObject.get("username").getAsString(),UUID.fromString(jsonObject.get("selected_profile").getAsJsonObject().get("id").getAsString())); } catch (IOException var14) { throw new AuthFailureException(String.format("Authentication error. Request could not be made! Cause: '%s'", var14.getMessage())); } @@ -127,38 +123,58 @@ public class MinecraftAuthenticator extends Authenticator { public MinecraftProfile getGameProfile(MinecraftToken minecraftToken) { try { + if(isForceMigrated(minecraftToken)) { + // this request is completly useless.... + return new MinecraftProfile(minecraftToken.getUuid(),minecraftToken.getUsername()); + } URL url = new URL("https://api.minecraftservices.com/minecraft/profile"); URLConnection urlConnection = url.openConnection(); HttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection; httpURLConnection.setRequestMethod("GET"); - httpURLConnection.setRequestProperty("Authorization", "Bearer " + minecraftToken.getAccessToken()); - httpURLConnection.setRequestProperty("Host", "api.minecraftservices.com"); + httpURLConnection.setRequestProperty("Authorization", "Bearer "+minecraftToken.getAccessToken()); httpURLConnection.connect(); JsonObject jsonObject = this.parseResponseData(httpURLConnection); + UUID uuid = this.generateUUID(jsonObject.get("id").getAsString()); String name = jsonObject.get("name").getAsString(); + return new MinecraftProfile(uuid, name); } catch (IOException var10) { throw new AuthFailureException(String.format("Authentication error. Request could not be made! Cause: '%s'", var10.getMessage())); } } + public boolean isForceMigrated(MinecraftToken minecraftToken) { + try { + URL url = new URL("https://api.minecraftservices.com/rollout/v1/msamigrationforced"); + URLConnection urlConnection = url.openConnection(); + HttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection; + httpURLConnection.setRequestMethod("GET"); + httpURLConnection.setRequestProperty("Authorization", "Bearer "+minecraftToken.getAccessToken()); + httpURLConnection.connect(); + JsonObject jsonObject = this.parseResponseData(httpURLConnection); + boolean rollout = jsonObject.get("rollout").getAsBoolean(); + + + return rollout; + } catch (IOException var10) { + throw new AuthFailureException(String.format("Authentication error. Request could not be made! Cause: '%s'", var10.getMessage())); + } + } public JsonObject parseResponseData(HttpURLConnection httpURLConnection) throws IOException { - BufferedReader bufferedReader; - if (httpURLConnection.getResponseCode() != 200) { - bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getErrorStream())); - } else { - bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())); - } - String lines = (String)bufferedReader.lines().collect(Collectors.joining()); - JsonObject jsonObject = (JsonObject)this.gson.fromJson(lines, JsonObject.class); - if (jsonObject.has("error")) { - throw new AuthFailureException(String.format("Could not find profile!. Error: '%s'", jsonObject.get("errorMessage").getAsString())); - } else { - return jsonObject; + InputStream stream = httpURLConnection.getInputStream(); + + StringBuilder textBuilder = new StringBuilder(); + try (Reader reader = new BufferedReader(new InputStreamReader + (stream, Charset.forName(StandardCharsets.UTF_8.name())))) { + int c = 0; + while ((c = reader.read()) != -1) { + textBuilder.append((char) c); + } } + return this.gson.fromJson(textBuilder.toString(),JsonObject.class); } public UUID generateUUID(String trimmedUUID) throws IllegalArgumentException { diff --git a/src/main/java/me/x150/authlib/login/mojang/MinecraftToken.java b/src/main/java/me/x150/authlib/login/mojang/MinecraftToken.java index 45a933b..5cff5e4 100644 --- a/src/main/java/me/x150/authlib/login/mojang/MinecraftToken.java +++ b/src/main/java/me/x150/authlib/login/mojang/MinecraftToken.java @@ -1,15 +1,28 @@ package me.x150.authlib.login.mojang; +import java.util.UUID; + public class MinecraftToken { private String accessToken; private String username; + private UUID uuid; + + public MinecraftToken() { } - public MinecraftToken(String accessToken, String username) { + public MinecraftToken(String accessToken, String username, UUID uuid) { this.accessToken = accessToken; this.username = username; + + this.uuid = uuid; + } + + + + public UUID getUuid() { + return uuid; } public String getAccessToken() { @@ -20,6 +33,7 @@ public class MinecraftToken { return this.username; } + public String toString() { return "MinecraftToken{accessToken='" + this.accessToken + '\'' + ", username='" + this.username + '\'' + '}'; } diff --git a/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java b/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java index fab1104..cf6a1be 100644 --- a/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java +++ b/src/main/java/net/shadow/client/feature/gui/screen/AltManagerScreen.java @@ -819,6 +819,7 @@ public class AltManagerScreen extends ClientScreen implements FastTickable { } void downloadTexture() { + if(this.storage.cachedUuid == null) return; this.tex = PlayerHeadResolver.resolve(this.storage.cachedUuid); } @@ -850,7 +851,6 @@ public class AltManagerScreen extends ClientScreen implements FastTickable { throw new NullPointerException(); } storage.accessToken = token.getAccessToken(); - MinecraftProfile profile = auth.getGameProfile(token); storage.cachedName = profile.getUsername(); storage.cachedUuid = profile.getUuid();