Inceptum/src/main/java/io/gitlab/jfronny/inceptum/windows/MicrosoftLoginWindow.java

190 lines
7.7 KiB
Java

package io.gitlab.jfronny.inceptum.windows;
import imgui.ImGui;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.microsoft.*;
import io.gitlab.jfronny.inceptum.util.account.AccountManager;
import io.gitlab.jfronny.inceptum.util.account.MicrosoftAccount;
import io.gitlab.jfronny.inceptum.util.account.MicrosoftAuthAPI;
import io.gitlab.jfronny.inceptum.util.Utils;
import net.freeutils.httpserver.HTTPServer;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
public class MicrosoftLoginWindow extends Window {
private static HTTPServer server = new HTTPServer(28562);
private static HTTPServer.VirtualHost host = server.getVirtualHost(null);
private static final String MICROSOFT_LOGIN_URL = "https://login.live.com/oauth20_authorize.srf?client_id=90890812-00d1-48a8-8d3f-38465ef43b58&prompt=select_account&cobrandid=8058f65d-ce06-4c30-9559-473c9275a65d&response_type=code&scope=XboxLive.signin%20XboxLive.offline_access&redirect_uri=http%3A%2F%2F127.0.0.1%3A28562";
private MicrosoftAccount account;
public MicrosoftLoginWindow() {
this(null);
}
public MicrosoftLoginWindow(MicrosoftAccount account) {
super("Microsoft Login");
this.account = account;
try {
startServer();
} catch (Exception e) {
Inceptum.LOGGER.error("Could not start mc login server", e);
}
}
@Override
public void draw() {
ImGui.text("This feature uses modified ATLauncher code");
ImGui.text("Click the button below to begin");
if (ImGui.button("Open in Browser")) {
try {
Utils.openWebBrowser(new URI(MICROSOFT_LOGIN_URL));
} catch (URISyntaxException e) {
Inceptum.LOGGER.error("Could not open browser", e);
}
}
}
private void startServer() throws Exception {
host.addContext("/", (req, res) -> {
if (req.getParams().containsKey("error")) {
res.getHeaders().add("Content-Type", "text/plain");
res.send(500, "Error logging in. Check console for more information");
Inceptum.LOGGER.error("Error logging into Microsoft account: " + URLDecoder
.decode(req.getParams().get("error_description"), StandardCharsets.UTF_8.toString()));
close();
return 0;
}
if (!req.getParams().containsKey("code")) {
res.getHeaders().add("Content-Type", "text/plain");
res.send(400, "Code is missing");
close();
return 0;
}
try {
acquireAccessToken(req.getParams().get("code"));
} catch (Exception e) {
Inceptum.LOGGER.error("Error acquiring accessToken", e);
res.getHeaders().add("Content-Type", "text/html");
res.send(500, "Error logging in. Check console for more information");
close();
return 0;
}
res.getHeaders().add("Content-Type", "text/plain");
// #. {0} is the name of the launcher
res.send(200, "Login complete. You can now close this window and go back to GLaunch");
close();
return 0;
}, "GET");
server.start();
}
private void acquireAccessToken(String authcode) throws Exception {
OauthTokenResponse oauthTokenResponse = MicrosoftAuthAPI.tradeCodeForAccessToken(authcode);
acquireXBLToken(oauthTokenResponse);
}
private void acquireXBLToken(OauthTokenResponse oauthTokenResponse) throws Exception {
XboxLiveAuthResponse xblAuthResponse = MicrosoftAuthAPI.getXBLToken(oauthTokenResponse.accessToken);
acquireXsts(oauthTokenResponse, xblAuthResponse.token);
}
private void acquireXsts(OauthTokenResponse oauthTokenResponse, String xblToken) throws Exception {
XboxLiveAuthResponse xstsAuthResponse = null;
xstsAuthResponse = MicrosoftAuthAPI.getXstsToken(xblToken);
/*try {
xstsAuthResponse = MicrosoftAuthAPI.getXstsToken(xblToken);
} catch (DownloadException e) {
if (e.response != null) {
GLaunch.LOGGER.debug(Gsons.DEFAULT.toJson(e.response));
XboxLiveAuthErrorResponse xboxLiveAuthErrorResponse = Gsons.DEFAULT.fromJson(e.response,
XboxLiveAuthErrorResponse.class);
String error = xboxLiveAuthErrorResponse.getErrorMessageForCode();
if (error != null) {
GLaunch.LOGGER.warn(error);
DialogManager.okDialog().setTitle("Error logging into Xbox Live")
.setContent(new HTMLBuilder().center().text(error).build()).setType(DialogManager.ERROR)
.show();
String link = xboxLiveAuthErrorResponse.getBrowserLinkForCode();
if (link != null) {
Utils.openWebBrowser(new URI(link));
}
}
throw e;
}
}*/
if (xstsAuthResponse != null) {
acquireMinecraftToken(oauthTokenResponse, xstsAuthResponse);
}
}
private void acquireMinecraftToken(OauthTokenResponse oauthTokenResponse, XboxLiveAuthResponse xstsAuthResponse) throws Exception {
String xblUhs = xstsAuthResponse.displayClaims.xui.get(0).uhs;
String xblXsts = xstsAuthResponse.token;
LoginResponse loginResponse = MicrosoftAuthAPI.loginToMinecraft("XBL3.0 x=" + xblUhs + ";" + xblXsts);
Store store = MicrosoftAuthAPI.getMcEntitlements(loginResponse.accessToken);
Inceptum.LOGGER.info(Inceptum.GSON.toJson(store));
if (!(store.items.stream().anyMatch(i -> i.name.equalsIgnoreCase("product_minecraft"))
&& store.items.stream().anyMatch(i -> i.name.equalsIgnoreCase("game_minecraft")))) {
Inceptum.open(new AlertWindow("This account doesn't have a valid purchase of Minecraft.\nPlease make sure you've bought the Java edition of Minecraft and then try again."));
throw new Exception("Account does not own Minecraft");
}
Profile profile = MicrosoftAuthAPI.getMcProfile(loginResponse.accessToken);
if (profile == null) {
throw new Exception("Failed to get Minecraft profile");
}
// add the account
addAccount(oauthTokenResponse, xstsAuthResponse, loginResponse, profile);
}
private void addAccount(OauthTokenResponse oauthTokenResponse, XboxLiveAuthResponse xstsAuthResponse,
LoginResponse loginResponse, Profile profile) throws Exception {
if (account != null || AccountManager.isAccountByName(loginResponse.username)) {
MicrosoftAccount account = (MicrosoftAccount) AccountManager.getAccountByName(loginResponse.username);
if (account == null) {
return;
}
// if forced to relogin, then make sure they logged into correct account
if (account != null && this.account != null && account.accountId != this.account.accountId) {
Inceptum.open(new AlertWindow("Logged into incorrect account. Please login again on the Accounts tab"));
return;
}
account.update(oauthTokenResponse, xstsAuthResponse, loginResponse, profile);
AccountManager.saveAccounts();
} else {
MicrosoftAccount account = new MicrosoftAccount(oauthTokenResponse, xstsAuthResponse, loginResponse,
profile);
AccountManager.addAccount(account);
}
}
}