- Simplified MS demo login message.
- Experimental multithread assets download implementation.
- Remove some commented out code blocks
This commit is contained in:
khanhduytran0 2021-06-30 17:28:42 +07:00
parent cb82ff5e50
commit e726179364
3 changed files with 21 additions and 212 deletions

View File

@ -108,206 +108,5 @@ public class MicrosoftAuthTask extends AsyncTask<String, Void, Object> {
listener.onFailed((Throwable) result);
}
}
// Based on https://github.com/MiniDigger/MiniLauncher/blob/master/launcher/src/main/java/me/minidigger/minecraftlauncher/launcher/gui/MsaFragmentController.java
/*
MIT License
Copyright (c) 2018 Ammar Ahmad
Copyright (c) 2018 Martin Benndorf
Copyright (c) 2018 Mark Vainomaa
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
private final class XSTSXUI {
private String uhs;
}
private final class XSTSDisplayClaims {
private XSTSXUI[] xui;
}
private final class GlobalToken {
// MSA AccessToken
private String access_token;
// XBL, XSTS Token
private String Token;
// XSTS
private XSTSDisplayClaims DisplayClaims;
// Minecraft side
private String id;
private String name;
}
private String acquireAccessToken(String authcode) throws IOException, URISyntaxException{
URI uri = new URI(authTokenUrl);
Map<Object, Object> data = new ArrayMap<>();
data.put("client_id", "00000000402b5328");
data.put("code", authcode);
data.put("grant_type", "authorization_code");
data.put("redirect_url", "https://login.live.com/oauth20_desktop.srf");
data.put("scope", "service::user.auth.xboxlive.com::MBI_SSL");
HttpRequest request = HttpRequest.newBuilder(uri)
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(ofFormData(data)).build();
HttpResponse resp = HttpClient.newBuilder().build().sendRequest(request, HttpResponse.BodyHandlers.ofString());
if (resp.statusCode() >= 200 && resp.statusCode() < 300) {
return Tools.GLOBAL_GSON.fromJson((String) resp.body(), GlobalToken.class).access_token;
} else {
throw new RuntimeException("Error " + resp.statusCode() + ": " + (String) resp.body());
}
}
private String acquireXBLToken(String accessToken) throws IOException, URISyntaxException {
URI uri = new URI(xblAuthUrl);
Map<Object, Object> dataProp = new ArrayMap<>();
dataProp.put("AuthMethod", "RPS");
dataProp.put("SiteName", "user.auth.xboxlive.com");
dataProp.put("RpsTicket", accessToken);
Map<Object, Object> data = new ArrayMap<>();
data.put("Properties", dataProp);
data.put("RelyingParty", "http://auth.xboxlive.com");
data.put("TokenType", "JWT");
HttpRequest request = HttpRequest.newBuilder(uri)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(ofJSONData(data)).build();
HttpResponse resp = HttpClient.newBuilder().build().sendRequest(request, HttpResponse.BodyHandlers.ofString());
if (resp.statusCode() >= 200 && resp.statusCode() < 300) {
return Tools.GLOBAL_GSON.fromJson((String) resp.body(), GlobalToken.class).Token;
} else {
throw new RuntimeException("Error " + resp.statusCode() + ": " + (String) resp.body());
}
}
private String[] acquireXsts(String xblToken) throws IOException, URISyntaxException {
URI uri = new URI(xstsAuthUrl);
Map<Object, Object> dataProp = new ArrayMap<>();
dataProp.put("SandboxId", "RETAIL");
dataProp.put("UserTokens", Arrays.asList(xblToken));
Map<Object, Object> data = new ArrayMap<>();
data.put("Properties", dataProp);
data.put("RelyingParty", "rp://api.minecraftservices.com/");
data.put("TokenType", "JWT");
HttpRequest request = HttpRequest.newBuilder(uri)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(ofJSONData(data)).build();
HttpResponse resp = HttpClient.newBuilder().build().sendRequest(request, HttpResponse.BodyHandlers.ofString());
if (resp.statusCode() >= 200 && resp.statusCode() < 300) {
String body = (String) resp.body();
GlobalToken token = Tools.GLOBAL_GSON.fromJson(body, GlobalToken.class);
String xblXsts = token.Token;
String uhs = token.DisplayClaims.xui[0].uhs;
return new String[]{uhs, xblXsts};
} else {
throw new RuntimeException("Error " + resp.statusCode() + ": " + (String) resp.body());
}
}
private String acquireMinecraftToken(String xblUhs, String xblXsts) throws IOException, URISyntaxException {
URI uri = new URI(mcLoginUrl);
Map<Object, Object> data = new ArrayMap<>();
data.put("identityToken", "XBL3.0 x=" + xblUhs + ";" + xblXsts);
HttpRequest request = HttpRequest.newBuilder(uri)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(ofJSONData(data)).build();
HttpResponse resp = HttpClient.newBuilder().build().sendRequest(request, HttpResponse.BodyHandlers.ofString());
if (resp.statusCode() >= 200 && resp.statusCode() < 300) {
String body = (String) resp.body();
return Tools.GLOBAL_GSON.fromJson(body, GlobalToken.class).access_token;
} else {
throw new RuntimeException("Error " + resp.statusCode() + ": " + (String) resp.body());
}
}
private MinecraftAccount checkMcProfile(String mcAccessToken) throws IOException, URISyntaxException {
URI uri = new URI(mcProfileUrl);
HttpRequest request = HttpRequest.newBuilder(uri)
.header("Authorization", "Bearer " + mcAccessToken)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.GET().build();
HttpResponse resp = HttpClient.newBuilder().build().sendRequest(request, HttpResponse.BodyHandlers.ofString());
if (resp.statusCode() >= 200 && resp.statusCode() < 300) {
String body = (String) resp.body();
GlobalToken token = Tools.GLOBAL_GSON.fromJson(body, GlobalToken.class);
String uuid = token.id;
String uuidDashes = uuid.replaceFirst(
"(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", "$1-$2-$3-$4-$5"
);
MinecraftAccount acc = new MinecraftAccount();
acc.isMicrosoft = true;
acc.username = token.name;
acc.accessToken = mcAccessToken;
acc.profileId = uuidDashes;
return acc;
} else {
throw new RuntimeException("Error " + resp.statusCode() + ": " + (String) resp.body());
}
}
public static HttpRequest.BodyPublisher ofJSONData(Map<Object, Object> data) {
return HttpRequest.BodyPublishers.ofString(Tools.GLOBAL_GSON.toJson(data));
}
public static HttpRequest.BodyPublisher ofFormData(Map<Object, Object> data) {
StringBuilder builder = new StringBuilder();
for (Map.Entry<Object, Object> entry : data.entrySet()) {
if (builder.length() > 0) {
builder.append("&");
}
try {
builder.append(URLEncoder.encode(entry.getKey().toString(), "UTF-8"));
builder.append("=");
builder.append(URLEncoder.encode(entry.getValue().toString(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
return HttpRequest.BodyPublishers.ofString(builder.toString());
}
*/
}

View File

@ -287,7 +287,7 @@ public class Msa {
errStr.contains("The server has not found anything matching the request URI"))
{
// TODO localize this
otherErrStr = "Can't login a demo account! Haven't you bought Minecraft: Java Edition on your account? Don't expect that Microsoft/Xbox account will give you free **paid/premium** MC Java account!";
otherErrStr = "It seems that this Microsoft Account does not own the game. Make sure that you have bought/migrated to your Microsoft account.";
}
throw new RuntimeException(otherErrStr + "\n\nMSA Error: " + conn.getResponseCode() + ": " + conn.getResponseMessage() + ", error stream:\n" + errStr);

View File

@ -363,7 +363,11 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
}
}
public void downloadAssets(JAssets assets, String assetsVersion, File outputDir) throws IOException, Throwable {
public void downloadAssets(final JAssets assets, String assetsVersion, final File outputDir) throws IOException {
ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(100);
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 40, 100, TimeUnit.SECONDS, workQueue, handler);
File hasDownloadedFile = new File(outputDir, "downloaded/" + assetsVersion + ".downloaded");
if (!hasDownloadedFile.exists()) {
System.out.println("Assets begin time: " + System.currentTimeMillis());
@ -371,23 +375,29 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
mActivity.mLaunchProgress.setMax(assetsObjects.size());
zeroProgress();
File objectsDir = new File(outputDir, "objects");
int downloadedSs = 0;
for (JAssetInfo asset : assetsObjects.values()) {
if (!mActivity.mIsAssetsProcessing) {
return;
}
executor.execute(() -> {
if (!mActivity.mIsAssetsProcessing) {
return;
}
if(!assets.map_to_resources) downloadAsset(asset, objectsDir);
else downloadAssetMapped(asset,(assetsObjects.keySet().toArray(new String[0])[downloadedSs]),outputDir);
publishProgress("1", mActivity.getString(R.string.mcl_launch_downloading, assetsObjects.keySet().toArray(new String[0])[downloadedSs]));
downloadedSs++;
try {
if(!assets.map_to_resources) downloadAsset(asset, objectsDir);
else downloadAssetMapped(asset,(assetsObjects.keySet().toArray(new String[0])[downloadedSs]),outputDir);
} catch (IOException e) {
e.printStackTrace();
mIsAssetsProcessing = false;
}
currProgress++;
downloadedSs++;
});
}
hasDownloadedFile.getParentFile().mkdirs();
hasDownloadedFile.createNewFile();
System.out.println("Assets end time: " + System.currentTimeMillis());
}
}
private JMinecraftVersionList.Version findVersion(String version) {
if (mActivity.mVersionList != null) {