Skip to content

Commit

Permalink
Feat[downloader]: Implement checksum downloading
Browse files Browse the repository at this point in the history
  • Loading branch information
artdeell committed Jan 27, 2025
1 parent 4fd0d0a commit e452b9a
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
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 @@ -368,6 +368,8 @@ private void scheduleGameJarDownload(MinecraftClientInfo minecraftClientInfo, St
mSourceJarFile = clientJar;
}



private static byte[] getLocalBuffer() {
byte[] tlb = sThreadLocalDownloadBuffer.get();
if(tlb != null) return tlb;
Expand Down Expand Up @@ -395,6 +397,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();
}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;
}
// The hash is a 40-byte download.
mInternetUsageCounter.getAndAdd(40);
}

@Override
public void run() {
try {
Expand All @@ -405,6 +441,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

0 comments on commit e452b9a

Please sign in to comment.