feat: load downloaded java installations.

This commit is contained in:
huanghongxun 2021-05-24 20:46:31 +08:00
parent e8a64f52f0
commit f2d3d24338
7 changed files with 108 additions and 47 deletions

View File

@ -22,14 +22,13 @@ import javafx.stage.Stage;
import org.jackhuang.hmcl.Launcher;
import org.jackhuang.hmcl.auth.*;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDownloadException;
import org.jackhuang.hmcl.download.DefaultCacheRepository;
import org.jackhuang.hmcl.download.DefaultDependencyManager;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.download.MaintainTask;
import org.jackhuang.hmcl.download.game.GameAssetIndexDownloadTask;
import org.jackhuang.hmcl.download.game.GameVerificationFixTask;
import org.jackhuang.hmcl.download.game.LibraryDownloadException;
import org.jackhuang.hmcl.download.java.JavaDownloadTask;
import org.jackhuang.hmcl.download.java.JavaRepository;
import org.jackhuang.hmcl.launch.NotDecompressingNativesException;
import org.jackhuang.hmcl.launch.PermissionException;
import org.jackhuang.hmcl.launch.ProcessCreationException;
@ -57,7 +56,6 @@ import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
import org.jackhuang.hmcl.util.i18n.I18n;
import org.jackhuang.hmcl.util.io.ResponseCodeException;
import org.jackhuang.hmcl.util.platform.*;
import org.jackhuang.hmcl.util.platform.JavaVersion;
import org.jackhuang.hmcl.util.versioning.VersionNumber;
import java.io.File;
@ -463,13 +461,13 @@ public final class LauncherHelper {
onAccept.run();
}
private static CompletableFuture<Void> downloadJava(org.jackhuang.hmcl.game.JavaVersion javaVersion, Profile profile) {
private static CompletableFuture<Void> downloadJava(GameJavaVersion javaVersion, Profile profile) {
CompletableFuture<Void> future = new CompletableFuture<>();
TaskExecutorDialogPane javaDownloadingPane = new TaskExecutorDialogPane(it -> {});
TaskExecutorDialogPane javaDownloadingPane = new TaskExecutorDialogPane(it -> {
});
TaskExecutor executor = new JavaDownloadTask(javaVersion,
DefaultCacheRepository.getInstance().getCacheDirectory().resolve("java"),
TaskExecutor executor = JavaRepository.downloadJava(javaVersion,
profile.getDependency().getDownloadProvider()).executor(false);
executor.addTaskListener(new TaskListener() {
@Override

View File

@ -27,6 +27,7 @@ import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.jackhuang.hmcl.Launcher;
import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.download.java.JavaRepository;
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.task.TaskExecutor;
@ -125,7 +126,7 @@ public final class Controllers {
dialog(i18n("launcher.cache_directory.invalid"));
}
Task.runAsync(JavaVersion::initialize).start();
Task.runAsync(JavaVersion::initialize).thenRunAsync(JavaRepository::initialize).start();
scene = new Scene(decorator.getDecorator());
scene.setFill(Color.TRANSPARENT);

View File

@ -20,13 +20,13 @@ package org.jackhuang.hmcl.download.java;
import org.jackhuang.hmcl.download.ArtifactMalformedException;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.game.DownloadInfo;
import org.jackhuang.hmcl.game.GameJavaVersion;
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.FileUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.versioning.VersionNumber;
import org.tukaani.xz.LZMAInputStream;
@ -41,14 +41,14 @@ import java.util.*;
import java.util.stream.Collectors;
public class JavaDownloadTask extends Task<Void> {
private final org.jackhuang.hmcl.game.JavaVersion javaVersion;
private final GameJavaVersion javaVersion;
private final Path rootDir;
private String platform;
private final Task<RemoteFiles> javaDownloadsTask;
private JavaDownloads.JavaDownload download;
private final List<Task<?>> dependencies = new ArrayList<>();
public JavaDownloadTask(org.jackhuang.hmcl.game.JavaVersion javaVersion, Path rootDir, DownloadProvider downloadProvider) {
public JavaDownloadTask(GameJavaVersion javaVersion, Path rootDir, DownloadProvider downloadProvider) {
this.javaVersion = javaVersion;
this.rootDir = rootDir;
this.javaDownloadsTask = new GetTask(NetworkUtils.toURL(
@ -77,7 +77,7 @@ public class JavaDownloadTask extends Task<Void> {
@Override
public void preExecute() throws Exception {
this.platform = getCurrentJavaPlatform().orElseThrow(UnsupportedPlatformException::new);
this.platform = JavaRepository.getCurrentJavaPlatform().orElseThrow(UnsupportedPlatformException::new);
}
@Override
@ -96,6 +96,7 @@ public class JavaDownloadTask extends Task<Void> {
DownloadInfo download = file.getDownloads().get("lzma");
File tempFile = Files.createTempFile("hmcl", "tmp").toFile();
FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(download.getUrl()), tempFile, new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1()));
task.setName(entry.getKey());
dependencies.add(task.thenRunAsync(() -> {
try {
Files.copy(new LZMAInputStream(new FileInputStream(tempFile)), dest);
@ -106,6 +107,7 @@ public class JavaDownloadTask extends Task<Void> {
} 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()));
task.setName(entry.getKey());
dependencies.add(task);
} else {
continue;
@ -142,26 +144,5 @@ public class JavaDownloadTask extends Task<Void> {
.collect(Collectors.joining(OperatingSystem.LINE_SEPARATOR)));
}
public static Optional<String> getCurrentJavaPlatform() {
if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
if (Architecture.CURRENT == Architecture.X86) {
return Optional.of("linux-i386");
} else if (Architecture.CURRENT == Architecture.X86_64) {
return Optional.of("linux");
}
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.OSX) {
if (Architecture.CURRENT == Architecture.X86_64) {
return Optional.of("mac-os");
}
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
if (Architecture.CURRENT == Architecture.X86) {
return Optional.of("windows-x86");
} else if (Architecture.CURRENT == Architecture.X86_64) {
return Optional.of("windows-x64");
}
}
return Optional.empty();
}
public static class UnsupportedPlatformException extends Exception {}
}

View File

@ -0,0 +1,83 @@
package org.jackhuang.hmcl.download.java;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.game.GameJavaVersion;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.CacheRepository;
import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.JavaVersion;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Logging.LOG;
public final class JavaRepository {
public static Task<?> downloadJava(GameJavaVersion javaVersion, DownloadProvider downloadProvider) {
return new JavaDownloadTask(javaVersion, getJavaStoragePath(), downloadProvider)
.thenRunAsync(() -> {
Optional<String> platform = getCurrentJavaPlatform();
if (platform.isPresent()) {
addJava(getJavaHome(javaVersion, platform.get()));
}
});
}
public static void addJava(Path javaHome) throws InterruptedException, IOException {
if (Files.isDirectory(javaHome)) {
Path executable = JavaVersion.getExecutable(javaHome);
if (Files.isRegularFile(executable)) {
JavaVersion.getJavas().add(JavaVersion.fromExecutable(executable));
}
}
}
public static void initialize() throws IOException, InterruptedException {
Optional<String> platformOptional = getCurrentJavaPlatform();
if (platformOptional.isPresent()) {
String platform = platformOptional.get();
for (Path component : Files.newDirectoryStream(getJavaStoragePath())) {
Path javaHome = component.resolve(platform).resolve(component.getFileName());
try {
addJava(javaHome);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to determine Java at " + javaHome, e);
}
}
}
}
public static Optional<String> getCurrentJavaPlatform() {
if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
if (Architecture.CURRENT == Architecture.X86) {
return Optional.of("linux-i386");
} else if (Architecture.CURRENT == Architecture.X86_64) {
return Optional.of("linux");
}
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.OSX) {
if (Architecture.CURRENT == Architecture.X86_64) {
return Optional.of("mac-os");
}
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
if (Architecture.CURRENT == Architecture.X86) {
return Optional.of("windows-x86");
} else if (Architecture.CURRENT == Architecture.X86_64) {
return Optional.of("windows-x64");
}
}
return Optional.empty();
}
public static Path getJavaStoragePath() {
return CacheRepository.getInstance().getCacheDirectory().resolve("java");
}
public static Path getJavaHome(GameJavaVersion javaVersion, String platform) {
return getJavaStoragePath().resolve(javaVersion.getComponent()).resolve(platform).resolve(javaVersion.getComponent());
}
}

View File

@ -17,15 +17,15 @@
*/
package org.jackhuang.hmcl.game;
public class JavaVersion {
public class GameJavaVersion {
private final String component;
private final int majorVersion;
public JavaVersion() {
public GameJavaVersion() {
this("", 0);
}
public JavaVersion(String component, int majorVersion) {
public GameJavaVersion(String component, int majorVersion) {
this.component = component;
this.majorVersion = majorVersion;
}

View File

@ -60,7 +60,7 @@ public class Version implements Comparable<Version>, Validation {
private final String assets;
private final Integer complianceLevel;
@Nullable
private final JavaVersion javaVersion;
private final GameJavaVersion javaVersion;
private final List<Library> libraries;
private final List<CompatibilityRule> compatibilityRules;
private final JsonMap<DownloadType, DownloadInfo> downloads;
@ -93,7 +93,7 @@ public class Version implements Comparable<Version>, Validation {
this(false, id, version, priority, null, arguments, mainClass, null, null, null, null, null, null, libraries, null, null, null, null, null, null, null, null, null, null);
}
public Version(boolean resolved, String id, String version, Integer priority, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, Integer complianceLevel, JavaVersion javaVersion, List<Library> libraries, List<CompatibilityRule> compatibilityRules, Map<DownloadType, DownloadInfo> downloads, Map<DownloadType, LoggingInfo> logging, ReleaseType type, Date time, Date releaseTime, Integer minimumLauncherVersion, Boolean hidden, Boolean root, List<Version> patches) {
public Version(boolean resolved, String id, String version, Integer priority, String minecraftArguments, Arguments arguments, String mainClass, String inheritsFrom, String jar, AssetIndexInfo assetIndex, String assets, Integer complianceLevel, GameJavaVersion javaVersion, List<Library> libraries, List<CompatibilityRule> compatibilityRules, Map<DownloadType, DownloadInfo> downloads, Map<DownloadType, LoggingInfo> logging, ReleaseType type, Date time, Date releaseTime, Integer minimumLauncherVersion, Boolean hidden, Boolean root, List<Version> patches) {
this.resolved = resolved;
this.id = id;
this.version = version;
@ -178,7 +178,7 @@ public class Version implements Comparable<Version>, Validation {
return complianceLevel;
}
public JavaVersion getJavaVersion() {
public GameJavaVersion getJavaVersion() {
return javaVersion;
}

View File

@ -28,9 +28,7 @@ import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
@ -38,7 +36,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.toList;
import static org.jackhuang.hmcl.util.Logging.LOG;
@ -144,7 +141,7 @@ public final class JavaVersion {
return javaVersion;
}
private static Path getExecutable(Path javaHome) {
public static Path getExecutable(Path javaHome) {
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
return javaHome.resolve("bin").resolve("java.exe");
} else {
@ -171,10 +168,10 @@ public final class JavaVersion {
Platform.PLATFORM);
}
private static List<JavaVersion> JAVAS;
private static Collection<JavaVersion> JAVAS;
private static final CountDownLatch LATCH = new CountDownLatch(1);
public static List<JavaVersion> getJavas() throws InterruptedException {
public static Collection<JavaVersion> getJavas() throws InterruptedException {
if (JAVAS != null)
return JAVAS;
LATCH.await();
@ -199,7 +196,8 @@ public final class JavaVersion {
javaVersions.add(CURRENT_JAVA);
}
JAVAS = unmodifiableList(javaVersions);
JAVAS = Collections.newSetFromMap(new ConcurrentHashMap<>());
JAVAS.addAll(javaVersions);
LATCH.countDown();
}