Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat[downloader]: Checksum downloading from libraries #6545

Merged
merged 4 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,29 @@ public static long getContentLengthMirrored(int downloadClass, String urlInput)
}
}

/**
* Download a file as a string from the current mirror. If the file does not exist on the mirror
* or the mirror returns an invalid string, request the file from the original source
* @param downloadClass Class of the download. Can either be DOWNLOAD_CLASS_LIBRARIES,
* DOWNLOAD_CLASS_METADATA or DOWNLOAD_CLASS_ASSETS
* @param urlInput The original (Mojang) URL for the download
* @return the contents of the downloaded file as a String.
*/
public static String downloadStringMirrored(int downloadClass, String urlInput) throws IOException{
String resultString = null;
try {
resultString = DownloadUtils.downloadString(getMirrorMapping(downloadClass,urlInput));
}catch (FileNotFoundException e) {
Log.w("DownloadMirror", "Failed to download string from mirror", e);
}
if(Tools.isValidString(resultString)) {
return resultString;
}else {
Log.w("DownloadMirror", "Downloaded string is invalid, falling back to default");
}
return DownloadUtils.downloadString(urlInput);
}

/**
* Check if the current download source is a mirror and not an official source.
* @return true if the source is a mirror, false otherwise
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,40 @@ private final class DownloaderTask implements Runnable, Tools.DownloaderFeedback
this.mSkipIfFailed = skipIfFailed;
}

private String downloadSha1() throws IOException {
String downloadedHash = DownloadMirror.downloadStringMirrored(
mDownloadClass, mTargetUrl + ".sha1"
);
if(!Tools.isValidString(downloadedHash)) return null;
// Ensure that we don't have leading/trailing whitespaces before checking hash length
downloadedHash = downloadedHash.trim();
// SHA1 is made up of 20 bytes, which means 40 hexadecimal digits, which means 40 chars
if(downloadedHash.length() != 40) return null;
return downloadedHash;
}

/*
* Maven repositories usually have the hash of a library near it, like:
* .../libraryName-1.0.jar
* .../libraryName.1.0.jar.sha1
* Since Minecraft libraries are stored in maven repositories, try to use
* this when downloading libraries without hashes in the json.
*/
private void tryGetLibrarySha1() {
String resultHash = null;
try {
resultHash = downloadSha1();
// The hash is a 40-byte download.
mInternetUsageCounter.getAndAdd(40);
}catch (IOException e) {
Log.i("MinecraftDownloader", "Failed to download hash", e);
}
if(resultHash != null) {
Log.i("MinecraftDownloader", "Got hash: "+resultHash+ " for "+FileUtils.getFileName(mTargetUrl));
mTargetSha1 = resultHash;
}
}

@Override
public void run() {
try {
Expand All @@ -405,6 +439,10 @@ public void run() {
}

private void runCatching() throws Exception {
if(mDownloadClass == DownloadMirror.DOWNLOAD_CLASS_LIBRARIES && !Tools.isValidString(mTargetSha1)) {
// If we're downloading a library, try to get sha1 since it might be available as a file
tryGetLibrarySha1();
}
if(Tools.isValidString(mTargetSha1)) {
verifyFileSha1();
}else {
Expand Down
Loading