Inceptum/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/account/MicrosoftAccount.java

212 lines
6.9 KiB
Java
Raw Normal View History

2022-09-04 21:21:24 +02:00
package io.gitlab.jfronny.inceptum.launcher.api.account;
2021-10-29 22:50:42 +02:00
import io.gitlab.jfronny.commons.ref.R;
2022-11-02 00:38:04 +01:00
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import io.gitlab.jfronny.inceptum.common.*;
2022-09-04 21:21:24 +02:00
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.launcher.gson.MicrosoftAccountAdapter;
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.*;
2022-11-02 00:38:04 +01:00
import io.gitlab.jfronny.inceptum.launcher.gson.MicrosoftAccountMeta;
2022-09-04 21:21:24 +02:00
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.*;
2021-10-29 22:50:42 +02:00
import java.io.IOException;
import java.net.URISyntaxException;
2022-09-04 21:21:24 +02:00
import java.util.*;
2021-10-29 22:50:42 +02:00
@GSerializable(with = MicrosoftAccountAdapter.class, configure = GsonPreset.Config.class)
2021-10-29 22:50:42 +02:00
public class MicrosoftAccount {
/**
* The username/email/id of the account.
*/
public String accountId;
/**
* The account's Minecraft username.
*/
public String minecraftUsername;
/**
* The UUID of the account.
*/
public String uuid;
/**
* The access token.
*/
public String accessToken;
/**
* The Microsoft oauth token.
*/
public OauthTokenResponse oauthToken;
/**
* The xsts auth response.
*/
public XboxLiveAuthResponse xstsAuth;
/**
* The date that the accessToken expires at.
*/
public Date accessTokenExpiresAt;
/**
* If the user must login again. This is usually the result of a failed
* accessToken refresh.
*/
public boolean mustLogin;
2022-11-02 00:38:04 +01:00
public MicrosoftAccount(MicrosoftAccountMeta meta) {
this.accountId = meta.accountId;
this.minecraftUsername = meta.minecraftUsername;
this.uuid = meta.uuid;
this.accessToken = meta.accessToken;
this.oauthToken = meta.oauthToken;
this.xstsAuth = meta.xstsAuth;
this.accessTokenExpiresAt = meta.accessTokenExpiresAt;
this.mustLogin = meta.mustLogin;
2022-11-02 00:38:04 +01:00
}
public MicrosoftAccountMeta toMeta() {
return new MicrosoftAccountMeta(
accountId,
minecraftUsername,
uuid,
accessToken,
oauthToken,
xstsAuth,
accessTokenExpiresAt,
mustLogin
);
}
2021-10-29 22:50:42 +02:00
public MicrosoftAccount(OauthTokenResponse oauthTokenResponse, XboxLiveAuthResponse xstsAuthResponse,
LoginResponse loginResponse, Profile profile) {
update(oauthTokenResponse, xstsAuthResponse, loginResponse, profile);
}
public void update(OauthTokenResponse oauthTokenResponse, XboxLiveAuthResponse xstsAuthResponse,
LoginResponse loginResponse, Profile profile) {
this.oauthToken = oauthTokenResponse;
this.xstsAuth = xstsAuthResponse;
this.accessToken = loginResponse.accessToken;
2021-10-29 22:50:42 +02:00
this.minecraftUsername = profile.name;
this.uuid = profile.id;
this.accountId = loginResponse.username;
2021-10-29 22:50:42 +02:00
this.mustLogin = false;
this.accessTokenExpiresAt = new Date();
this.accessTokenExpiresAt.time += loginResponse.expiresIn * 1000;
2021-10-29 22:50:42 +02:00
}
public String getAccessToken() {
return accessToken;
}
public String getSessionToken() {
return accessToken;
}
public String getCurrentUsername() throws IOException, URISyntaxException {
2021-10-29 22:50:42 +02:00
Profile profile = MicrosoftAuthAPI.getMcProfile(accessToken);
if (profile.name == null) throw new IOException("Got null name");
return profile.name;
2021-10-29 22:50:42 +02:00
}
public void updateSkinPreCheck() {
this.refreshAccessToken();
}
public String getSkinUrl() throws IOException, URISyntaxException {
2021-10-29 22:50:42 +02:00
Profile profile = MicrosoftAuthAPI.getMcProfile(accessToken);
return Optional.of(profile.skins).orElse(new ArrayList<>())
.stream()
.filter(s -> s.state.equalsIgnoreCase("ACTIVE"))
.findFirst()
.map(s -> s.url)
.orElse(null);
2021-10-29 22:50:42 +02:00
}
public boolean refreshAccessToken() {
return refreshAccessToken(false);
}
public boolean refreshAccessToken(boolean force) {
try {
if (force || new Date().after(this.oauthToken.expiresAt)) {
Utils.LOGGER.info("Oauth token expired. Attempting to refresh");
2021-10-29 22:50:42 +02:00
OauthTokenResponse oauthTokenResponse = MicrosoftAuthAPI.refreshAccessToken(oauthToken.refreshToken);
if (oauthTokenResponse == null) {
mustLogin = true;
AccountManager.saveAccounts();
Utils.LOGGER.error("Failed to refresh accessToken");
2021-10-29 22:50:42 +02:00
return false;
}
this.oauthToken = oauthTokenResponse;
AccountManager.saveAccounts();
}
if (force || new Date().after(this.xstsAuth.notAfter)) {
Utils.LOGGER.info("xsts auth expired. Attempting to get new auth");
2021-10-29 22:50:42 +02:00
XboxLiveAuthResponse xboxLiveAuthResponse = MicrosoftAuthAPI.getXBLToken(this.oauthToken.accessToken);
this.xstsAuth = MicrosoftAuthAPI.getXstsToken(xboxLiveAuthResponse.token);
2021-10-29 22:50:42 +02:00
if (xstsAuth == null) {
mustLogin = true;
AccountManager.saveAccounts();
Utils.LOGGER.error("Failed to get XBLToken");
2021-10-29 22:50:42 +02:00
return false;
}
AccountManager.saveAccounts();
}
if (force || new Date().after(this.accessTokenExpiresAt)) {
LoginResponse loginResponse = MicrosoftAuthAPI.loginToMinecraft(identityToken);
2021-10-29 22:50:42 +02:00
if (loginResponse == null) {
mustLogin = true;
AccountManager.saveAccounts();
Utils.LOGGER.error("Failed to login to Minecraft");
2021-10-29 22:50:42 +02:00
return false;
}
this.accessToken = loginResponse.accessToken;
this.accountId = loginResponse.username;
2021-10-29 22:50:42 +02:00
this.accessTokenExpiresAt = new Date();
this.accessTokenExpiresAt.time += loginResponse.expiresIn * 1000;
2021-10-29 22:50:42 +02:00
AccountManager.saveAccounts();
}
} catch (Exception e) {
mustLogin = true;
AccountManager.saveAccounts();
Utils.LOGGER.error("Exception refreshing accessToken", e);
2021-10-29 22:50:42 +02:00
return false;
}
return true;
}
private String getIdentityToken() {
return "XBL3.0 x=" + xstsAuth.displayClaims.xui[0].uhs + ";" + xstsAuth.token;
2021-10-29 22:50:42 +02:00
}
2022-09-04 21:21:24 +02:00
public boolean ensureAccessTokenValid() {
2021-10-29 22:50:42 +02:00
if (mustLogin) {
2022-09-04 21:21:24 +02:00
LauncherEnv.showOkCancel("You must login again in order to continue", "Login expired", () -> LauncherEnv.showLoginRefreshPrompt(this), R::nop);
2021-10-30 19:26:59 +02:00
return false;
} else return true;
2021-10-29 22:50:42 +02:00
}
@Override
public String toString() {
return minecraftUsername;
}
}