diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java index 7c35f9375..a83eb0cdc 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java @@ -25,6 +25,7 @@ import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.GetTask; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.gson.JsonUtils; +import org.jackhuang.hmcl.util.io.ChecksumMismatchException; import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jackhuang.hmcl.util.platform.OperatingSystem; @@ -37,9 +38,13 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.stream.Collectors; +import static org.jackhuang.hmcl.util.Logging.LOG; + public class JavaDownloadTask extends Task { private final GameJavaVersion javaVersion; private final Path rootDir; @@ -47,10 +52,12 @@ public class JavaDownloadTask extends Task { private final Task javaDownloadsTask; private JavaDownloads.JavaDownload download; private final List> dependencies = new ArrayList<>(); + private final DownloadProvider downloadProvider; public JavaDownloadTask(GameJavaVersion javaVersion, Path rootDir, DownloadProvider downloadProvider) { this.javaVersion = javaVersion; this.rootDir = rootDir; + this.downloadProvider = downloadProvider; this.javaDownloadsTask = new GetTask(NetworkUtils.toURL(downloadProvider.injectURL( "https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"))) .thenComposeAsync(javaDownloadsJson -> { @@ -62,7 +69,7 @@ public class JavaDownloadTask extends Task { for (JavaDownloads.JavaDownload download : candidates) { if (VersionNumber.VERSION_COMPARATOR.compare(download.getVersion().getName(), Integer.toString(javaVersion.getMajorVersion())) >= 0) { this.download = download; - return new GetTask(NetworkUtils.toURL(download.getManifest().getUrl())); + return new GetTask(NetworkUtils.toURL(downloadProvider.injectURL(download.getManifest().getUrl()))); } } throw new UnsupportedPlatformException(); @@ -92,14 +99,29 @@ public class JavaDownloadTask extends Task { Path dest = jvmDir.resolve(entry.getKey()); if (entry.getValue() instanceof RemoteFiles.RemoteFile) { RemoteFiles.RemoteFile file = ((RemoteFiles.RemoteFile) entry.getValue()); + + // Use local file if it already exists + try { + BasicFileAttributes localFileAttributes = Files.readAttributes(dest, BasicFileAttributes.class); + if (localFileAttributes.isRegularFile() && file.getDownloads().containsKey("raw")) { + DownloadInfo downloadInfo = file.getDownloads().get("raw"); + if (localFileAttributes.size() == downloadInfo.getSize()) { + ChecksumMismatchException.verifyChecksum(dest, "SHA-1", downloadInfo.getSha1()); + LOG.info("Skip existing file: " + dest); + continue; + } + } + } catch (IOException ignored) { + } + if (file.getDownloads().containsKey("lzma")) { DownloadInfo download = file.getDownloads().get("lzma"); File tempFile = jvmDir.resolve(entry.getKey() + ".lzma").toFile(); - FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(download.getUrl()), tempFile, new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); + FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(downloadProvider.injectURL(download.getUrl())), tempFile, new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); task.setName(entry.getKey()); dependencies.add(task.thenRunAsync(() -> { try (LZMAInputStream input = new LZMAInputStream(new FileInputStream(tempFile))) { - Files.copy(input, dest); + Files.copy(input, dest, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new ArtifactMalformedException("File " + entry.getKey() + " is malformed", e); } @@ -110,7 +132,7 @@ public class JavaDownloadTask extends Task { })); } else if (file.getDownloads().containsKey("raw")) { DownloadInfo download = file.getDownloads().get("raw"); - FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(download.getUrl()), dest.toFile(), new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); + FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(downloadProvider.injectURL(download.getUrl())), dest.toFile(), new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); task.setName(entry.getKey()); if (file.isExecutable()) { dependencies.add(task.thenRunAsync(() -> dest.toFile().setExecutable(true)));