mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 16:47:14 -04:00
Changes
- Simplified MS demo login message. - Experimental multithread assets download implementation. - Remove some commented out code blocks
This commit is contained in:
parent
cb82ff5e50
commit
e726179364
@ -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());
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user