mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-18 08:16:58 -04:00
parent
ba91c60e95
commit
e08ba4d421
@ -18,7 +18,6 @@
|
|||||||
package org.jackhuang.hmcl.download.game;
|
package org.jackhuang.hmcl.download.game;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.download.AbstractDependencyManager;
|
import org.jackhuang.hmcl.download.AbstractDependencyManager;
|
||||||
import org.jackhuang.hmcl.download.ArtifactMalformedException;
|
|
||||||
import org.jackhuang.hmcl.download.DefaultCacheRepository;
|
import org.jackhuang.hmcl.download.DefaultCacheRepository;
|
||||||
import org.jackhuang.hmcl.game.Library;
|
import org.jackhuang.hmcl.game.Library;
|
||||||
import org.jackhuang.hmcl.task.DownloadException;
|
import org.jackhuang.hmcl.task.DownloadException;
|
||||||
@ -26,13 +25,12 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
|
|||||||
import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck;
|
import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.DigestUtils;
|
import org.jackhuang.hmcl.util.DigestUtils;
|
||||||
import org.jackhuang.hmcl.util.Pack200Utils;
|
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
import org.tukaani.xz.XZInputStream;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -41,7 +39,6 @@ import java.util.*;
|
|||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarInputStream;
|
import java.util.jar.JarInputStream;
|
||||||
import java.util.jar.JarOutputStream;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||||
@ -51,10 +48,8 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
protected final File jar;
|
protected final File jar;
|
||||||
protected final DefaultCacheRepository cacheRepository;
|
protected final DefaultCacheRepository cacheRepository;
|
||||||
protected final AbstractDependencyManager dependencyManager;
|
protected final AbstractDependencyManager dependencyManager;
|
||||||
private final File xzFile;
|
|
||||||
protected final Library library;
|
protected final Library library;
|
||||||
protected final String url;
|
protected final String url;
|
||||||
protected boolean xz;
|
|
||||||
private final Library originalLibrary;
|
private final Library originalLibrary;
|
||||||
private boolean cached = false;
|
private boolean cached = false;
|
||||||
|
|
||||||
@ -72,8 +67,6 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
|
|
||||||
url = library.getDownload().getUrl();
|
url = library.getDownload().getUrl();
|
||||||
jar = file;
|
jar = file;
|
||||||
|
|
||||||
xzFile = new File(file.getAbsoluteFile().getParentFile(), file.getName() + ".pack.xz");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -101,8 +94,6 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
throw new CancellationException();
|
throw new CancellationException();
|
||||||
else
|
else
|
||||||
throw new LibraryDownloadException(library, t);
|
throw new LibraryDownloadException(library, t);
|
||||||
} else {
|
|
||||||
if (xz) unpackLibrary(jar, Files.readAllBytes(xzFile.toPath()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,36 +117,13 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pack200Utils.isSupported() && testURLExistence(url)) {
|
|
||||||
List<URL> urls = dependencyManager.getDownloadProvider().injectURLWithCandidates(url + ".pack.xz");
|
|
||||||
task = new FileDownloadTask(urls, xzFile, null);
|
|
||||||
task.setCacheRepository(cacheRepository);
|
|
||||||
task.setCaching(true);
|
|
||||||
xz = true;
|
|
||||||
} else {
|
|
||||||
List<URL> urls = dependencyManager.getDownloadProvider().injectURLWithCandidates(url);
|
|
||||||
task = new FileDownloadTask(urls, jar,
|
|
||||||
library.getDownload().getSha1() != null ? new IntegrityCheck("SHA-1", library.getDownload().getSha1()) : null);
|
|
||||||
task.setCacheRepository(cacheRepository);
|
|
||||||
task.setCaching(true);
|
|
||||||
task.addIntegrityCheckHandler(FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER);
|
|
||||||
xz = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean testURLExistence(String rawUrl) {
|
List<URL> urls = dependencyManager.getDownloadProvider().injectURLWithCandidates(url);
|
||||||
List<URL> urls = dependencyManager.getDownloadProvider().injectURLWithCandidates(rawUrl);
|
task = new FileDownloadTask(urls, jar,
|
||||||
for (URL url : urls) {
|
library.getDownload().getSha1() != null ? new IntegrityCheck("SHA-1", library.getDownload().getSha1()) : null);
|
||||||
URL xzURL = NetworkUtils.toURL(url.toString() + ".pack.xz");
|
task.setCacheRepository(cacheRepository);
|
||||||
for (int retry = 0; retry < 3; retry++) {
|
task.setCaching(true);
|
||||||
try {
|
task.addIntegrityCheckHandler(FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER);
|
||||||
return NetworkUtils.urlExists(xzURL);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.log(Level.WARNING, "Failed to test for url existence: " + url + ".pack.xz", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false; // maybe some ugly implementation will give timeout for not existent url.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -167,7 +135,7 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
public void postExecute() throws Exception {
|
public void postExecute() throws Exception {
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
try {
|
try {
|
||||||
cacheRepository.cacheLibrary(library, jar.toPath(), xz);
|
cacheRepository.cacheLibrary(library, jar.toPath(), false);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(Level.WARNING, "Failed to cache downloaded library " + library, e);
|
LOG.log(Level.WARNING, "Failed to cache downloaded library " + library, e);
|
||||||
}
|
}
|
||||||
@ -232,44 +200,4 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void unpackLibrary(File dest, byte[] src) throws IOException {
|
|
||||||
if (dest.exists())
|
|
||||||
if (!dest.delete())
|
|
||||||
throw new IOException("Unable to delete file " + dest);
|
|
||||||
|
|
||||||
byte[] decompressed;
|
|
||||||
try {
|
|
||||||
decompressed = IOUtils.readFullyAsByteArray(new XZInputStream(new ByteArrayInputStream(src)));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ArtifactMalformedException("Library " + dest + " is malformed");
|
|
||||||
}
|
|
||||||
|
|
||||||
String end = new String(decompressed, decompressed.length - 4, 4);
|
|
||||||
if (!end.equals("SIGN"))
|
|
||||||
throw new IOException("Unpacking failed, signature missing " + end);
|
|
||||||
|
|
||||||
int x = decompressed.length;
|
|
||||||
int len = decompressed[(x - 8)] & 0xFF | (decompressed[(x - 7)] & 0xFF) << 8 | (decompressed[(x - 6)] & 0xFF) << 16 | (decompressed[(x - 5)] & 0xFF) << 24;
|
|
||||||
|
|
||||||
Path temp = Files.createTempFile("minecraft", ".pack");
|
|
||||||
|
|
||||||
byte[] checksums = Arrays.copyOfRange(decompressed, decompressed.length - len - 8, decompressed.length - 8);
|
|
||||||
|
|
||||||
try (OutputStream out = Files.newOutputStream(temp)) {
|
|
||||||
out.write(decompressed, 0, decompressed.length - len - 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
try (FileOutputStream jarBytes = new FileOutputStream(dest); JarOutputStream jos = new JarOutputStream(jarBytes)) {
|
|
||||||
Pack200Utils.unpack(temp.toFile(), jos);
|
|
||||||
|
|
||||||
JarEntry checksumsFile = new JarEntry("checksums.sha1");
|
|
||||||
checksumsFile.setTime(0L);
|
|
||||||
jos.putNextEntry(checksumsFile);
|
|
||||||
jos.write(checksums);
|
|
||||||
jos.closeEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.delete(temp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user