Support packed update archive
This commit is contained in:
@@ -26,7 +26,10 @@ import java.nio.file.StandardCopyOption;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.jar.Attributes;
|
import java.util.jar.Attributes;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.jar.JarOutputStream;
|
||||||
|
import java.util.jar.Pack200;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.Launcher;
|
import org.jackhuang.hmcl.Launcher;
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
@@ -63,17 +66,26 @@ final class LocalRepository {
|
|||||||
* Creates a task that downloads the given version to local repository.
|
* Creates a task that downloads the given version to local repository.
|
||||||
*/
|
*/
|
||||||
public static FileDownloadTask downloadFromRemote(RemoteVersion version) throws IOException {
|
public static FileDownloadTask downloadFromRemote(RemoteVersion version) throws IOException {
|
||||||
Path stage = Files.createTempFile("hmcl-update-", ".jar");
|
Path stage = Files.createTempFile("hmcl-update-", "");
|
||||||
return new FileDownloadTask(new URL(version.getUrl()), stage.toFile(), version.getIntegrityCheck()) {
|
return new FileDownloadTask(new URL(version.getUrl()), stage.toFile(), version.getIntegrityCheck()) {
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
|
Path jar = stage;
|
||||||
try {
|
try {
|
||||||
super.execute();
|
super.execute();
|
||||||
IntegrityChecker.requireVerifiedJar(stage);
|
if (version.getType() == RemoteVersion.Type.PACK) {
|
||||||
|
Path unpacked = Files.createTempFile("hmcl-update-", ".jar");
|
||||||
|
try (GZIPInputStream stream = new GZIPInputStream(Files.newInputStream(jar));
|
||||||
|
JarOutputStream out = new JarOutputStream(Files.newOutputStream(unpacked))) {
|
||||||
|
Pack200.newUnpacker().unpack(stream, out);
|
||||||
|
}
|
||||||
|
jar = unpacked;
|
||||||
|
}
|
||||||
|
IntegrityChecker.requireVerifiedJar(jar);
|
||||||
Files.createDirectories(localStorage.getParent());
|
Files.createDirectories(localStorage.getParent());
|
||||||
Files.copy(stage, localStorage, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(jar, localStorage, StandardCopyOption.REPLACE_EXISTING);
|
||||||
} finally {
|
} finally {
|
||||||
Files.deleteIfExists(stage);
|
Files.deleteIfExists(jar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,9 +34,16 @@ public class RemoteVersion {
|
|||||||
try {
|
try {
|
||||||
JsonObject response = JsonUtils.fromNonNullJson(NetworkUtils.doGet(NetworkUtils.toURL(url)), JsonObject.class);
|
JsonObject response = JsonUtils.fromNonNullJson(NetworkUtils.doGet(NetworkUtils.toURL(url)), JsonObject.class);
|
||||||
String version = Optional.ofNullable(response.get("version")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("version is missing"));
|
String version = Optional.ofNullable(response.get("version")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("version is missing"));
|
||||||
String downloadUrl = Optional.ofNullable(response.get("jar")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("jar is missing"));
|
String jarUrl = Optional.ofNullable(response.get("jar")).map(JsonElement::getAsString).orElse(null);
|
||||||
String sha1 = Optional.ofNullable(response.get("jarsha1")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("jarsha1 is missing"));
|
String jarHash = Optional.ofNullable(response.get("jarsha1")).map(JsonElement::getAsString).orElse(null);
|
||||||
return new RemoteVersion(version, downloadUrl, new IntegrityCheck("SHA-1", sha1));
|
String packUrl = Optional.ofNullable(response.get("pack")).map(JsonElement::getAsString).orElse(null);
|
||||||
|
String packHash = Optional.ofNullable(response.get("packsha1")).map(JsonElement::getAsString).orElse(null);
|
||||||
|
if (packUrl != null && packHash != null)
|
||||||
|
return new RemoteVersion(version, packUrl, Type.PACK, new IntegrityCheck("SHA-1", packHash));
|
||||||
|
else if (jarUrl != null && jarHash != null)
|
||||||
|
return new RemoteVersion(version, jarUrl, Type.JAR, new IntegrityCheck("SHA-1", jarHash));
|
||||||
|
else
|
||||||
|
throw new IOException("Missing both jar and pack download URL");
|
||||||
} catch (JsonParseException e) {
|
} catch (JsonParseException e) {
|
||||||
throw new IOException("Malformed response", e);
|
throw new IOException("Malformed response", e);
|
||||||
}
|
}
|
||||||
@@ -44,11 +51,13 @@ public class RemoteVersion {
|
|||||||
|
|
||||||
private String version;
|
private String version;
|
||||||
private String url;
|
private String url;
|
||||||
|
private Type type;
|
||||||
private IntegrityCheck integrityCheck;
|
private IntegrityCheck integrityCheck;
|
||||||
|
|
||||||
public RemoteVersion(String version, String url, IntegrityCheck integrityCheck) {
|
public RemoteVersion(String version, String url, Type type, IntegrityCheck integrityCheck) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
|
this.type = type;
|
||||||
this.integrityCheck = integrityCheck;
|
this.integrityCheck = integrityCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +69,10 @@ public class RemoteVersion {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
public IntegrityCheck getIntegrityCheck() {
|
public IntegrityCheck getIntegrityCheck() {
|
||||||
return integrityCheck;
|
return integrityCheck;
|
||||||
}
|
}
|
||||||
@@ -68,4 +81,9 @@ public class RemoteVersion {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + version + " from " + url + "]";
|
return "[" + version + " from " + url + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
PACK,
|
||||||
|
JAR
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user