From 64a92b7768eb98997136f32576c565913ea7fed4 Mon Sep 17 00:00:00 2001 From: Glavo Date: Thu, 2 Sep 2021 23:19:26 +0800 Subject: [PATCH] ask the user whether to download javafx --- .../hmcl/util/SelfDependencyPatcher.java | 125 ++++++++++++++---- .../resources/assets/lang/I18N.properties | 6 + .../assets/lang/I18N_zh_CN.properties | 7 + 3 files changed, 112 insertions(+), 26 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java index b1ab83e3a..f97157d29 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java @@ -60,18 +60,9 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JProgressBar; -import javax.swing.SwingUtilities; -import javax.swing.WindowConstants; +import javax.swing.*; import org.jackhuang.hmcl.util.io.ChecksumMismatchException; import org.jackhuang.hmcl.util.io.IOUtils; @@ -88,7 +79,7 @@ public final class SelfDependencyPatcher { static class DependencyDescriptor { - private static final String REPOSITORY_URL = System.getProperty("hmcl.openjfx.repo", "https://maven.aliyun.com/repository/central/"); + // private static final String REPOSITORY_URL = System.getProperty("hmcl.openjfx.repo", "https://maven.aliyun.com/repository/central/"); private static final Path DEPENDENCIES_DIR_PATH = HMCL_DIRECTORY.resolve("dependencies"); private static String currentArchClassifier() { @@ -116,15 +107,54 @@ public final class SelfDependencyPatcher { return sha1.get(currentArchClassifier()); } - public String url() { - return REPOSITORY_URL + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + filename(); - } - public Path localPath() { return DEPENDENCIES_DIR_PATH.resolve(filename()); } } + static final class Repository { + public static final List REPOSITORIES; + + public static final Repository CUSTOM; + public static final Repository MAVEN_CENTRAL = new Repository(i18n("repositories.maven_central"), "https://repo1.maven.org/maven2"); + public static final Repository ALIYUN_MIRROR = new Repository(i18n("repositories.aliyun_mirror"), "https://maven.aliyun.com/repository/central"); + + public static final Repository DEFAULT; + + static { + final String customUrl = System.getProperty("hmcl.openjfx.repo"); + if (customUrl == null) { + CUSTOM = null; + if (System.getProperty("user.country", "").equalsIgnoreCase("CN")) { + DEFAULT = Repository.ALIYUN_MIRROR; + } else { + DEFAULT = Repository.MAVEN_CENTRAL; + } + REPOSITORIES = Collections.unmodifiableList(Arrays.asList(MAVEN_CENTRAL, ALIYUN_MIRROR)); + } else { + CUSTOM = new Repository(String.format(i18n("repositories.custom"), customUrl), customUrl); + DEFAULT = CUSTOM; + REPOSITORIES = Collections.unmodifiableList(Arrays.asList(MAVEN_CENTRAL, ALIYUN_MIRROR, CUSTOM)); + } + } + + private final String name; + private final String url; + + Repository(String name, String url) { + this.name = name; + this.url = url; + } + + public String resolveDependencyURL(DependencyDescriptor descriptor) { + return String.format("%s/%s/%s/%s/%s", + url, + descriptor.groupId.replace('.', '/'), + descriptor.artifactId, descriptor.version, + descriptor.filename()); + } + } + private static final String DEPENDENCIES_LIST_FILE = "/assets/openjfx-dependencies.json"; private static List readDependencies() { @@ -174,8 +204,10 @@ public final class SelfDependencyPatcher { // Download missing dependencies List missingDependencies = checkMissingDependencies(); if (!missingDependencies.isEmpty()) { + final Repository repository = showChooseRepositoryDialog(); + try { - fetchDependencies(missingDependencies); + fetchDependencies(repository, missingDependencies); } catch (IOException e) { throw new PatchException("Failed to download dependencies", e); } @@ -192,6 +224,43 @@ public final class SelfDependencyPatcher { LOG.info(" - Done!"); } + private static Repository showChooseRepositoryDialog() { + final JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + + for (String line : i18n("repositories.chooser").split("\n")) { + panel.add(new JLabel(line)); + } + + final ButtonGroup buttonGroup = new ButtonGroup(); + + for (Repository repository : Repository.REPOSITORIES) { + final JRadioButton button = new JRadioButton(repository.name); + button.putClientProperty("repository", repository); + buttonGroup.add(button); + panel.add(button); + if (repository == Repository.DEFAULT) { + button.setSelected(true); + } + } + + int res = JOptionPane.showConfirmDialog(null, panel, i18n("repositories.chooser.title"), JOptionPane.YES_NO_OPTION); + + if (res == JOptionPane.YES_OPTION) { + final Enumeration buttons = buttonGroup.getElements(); + while (buttons.hasMoreElements()) { + final AbstractButton button = buttons.nextElement(); + if (button.isSelected()) { + return (Repository) button.getClientProperty("repository"); + } + } + } else { + LOG.info("User choose not to download JavaFX"); + System.exit(0); + } + throw new AssertionError(); + } + /** * Inject them into the current classpath. * @@ -206,7 +275,7 @@ public final class SelfDependencyPatcher { .collect(toSet()); Path[] jars = JFX_DEPENDENCIES.stream() - .map(it -> it.localPath()) + .map(DependencyDescriptor::localPath) .toArray(Path[]::new); JavaFXPatcher.patch(modules, jars); @@ -217,27 +286,31 @@ public final class SelfDependencyPatcher { * * @throws IOException When the files cannot be fetched or saved. */ - private static void fetchDependencies(List dependencies) throws IOException { + private static void fetchDependencies(Repository repository, List dependencies) throws IOException { ProgressFrame dialog = new ProgressFrame(i18n("download.javafx")); dialog.setVisible(true); int progress = 0; for (DependencyDescriptor dependency : dependencies) { int currentProgress = ++progress; + final String url = repository.resolveDependencyURL(dependency); SwingUtilities.invokeLater(() -> { - dialog.setStatus(dependency.url()); + dialog.setStatus(url); dialog.setProgress(currentProgress, dependencies.size()); }); - LOG.info("Downloading " + dependency.url()); + LOG.info("Downloading " + url); Files.createDirectories(dependency.localPath().getParent()); - Files.copy(new URL(dependency.url()).openStream(), dependency.localPath(), StandardCopyOption.REPLACE_EXISTING); + try (InputStream is = new URL(url).openStream()) { + Files.copy(is, dependency.localPath(), StandardCopyOption.REPLACE_EXISTING); + } verifyChecksum(dependency); } dialog.dispose(); } + private static List checkMissingDependencies() { List missing = new ArrayList<>(); @@ -295,10 +368,10 @@ public final class SelfDependencyPatcher { setLocationRelativeTo(null); GridBagLayout gridBagLayout = new GridBagLayout(); - gridBagLayout.columnWidths = new int[] { 600, 0 }; - gridBagLayout.rowHeights = new int[] { 0, 0, 0, 200 }; - gridBagLayout.columnWeights = new double[] { 1.0, Double.MIN_VALUE }; - gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 1.0 }; + gridBagLayout.columnWidths = new int[]{600, 0}; + gridBagLayout.rowHeights = new int[]{0, 0, 0, 200}; + gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE}; + gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 1.0}; panel.setLayout(gridBagLayout); progressText = new JLabel(""); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index cf9036869..2e678fa68 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -490,6 +490,12 @@ profile.title=Game Directories profile.selected=Selected profile.use_relative_path=Use relative path for game directory if possible +repositories.custom=Custom Maven Repository (%s) +repositories.maven_central=Maven Central (General) +repositories.aliyun_mirror=Maven mirror for Aliyun (Chinese mainland) +repositories.chooser=JavaFX is missing. Do you want to automatically download and load OpenJFX from web?\nSelect download source: +repositories.chooser.title=Do you want to download JavaFX? + resourcepack=Resource Pack selector.choose=Choose diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index b7916dfe0..6e4758e73 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -495,6 +495,13 @@ profile.title=游戏目录 profile.selected=已选中 profile.use_relative_path=若可能,游戏目录使用相对路径 +repositories.custom=自定义 Maven 仓库(%s) +repositories.maven_central=Maven Central(通用) +repositories.aliyun_mirror=阿里云 Maven 镜像源(中国大陆) +repositories.chooser=JavaFX 缺失。是否需要从网络下载并加载 OpenJFX?\n请选择下载源: +repositories.chooser.title=是否下载 JavaFX? + + resourcepack=资源包 search=搜索