From f70ec8a090865377c5edb33b85104327cfc08b4a Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Tue, 19 Oct 2021 23:07:00 +0800 Subject: [PATCH] fix(launch): cannot launch far old versions on macOS. --- .../download/game/GameAssetDownloadTask.java | 17 +++---- .../game/GameAssetIndexDownloadTask.java | 11 ++--- .../hmcl/game/DefaultGameRepository.java | 44 ++++++++++--------- .../jackhuang/hmcl/game/GameRepository.java | 13 +++--- .../hmcl/launch/DefaultLauncher.java | 12 +++-- 5 files changed, 53 insertions(+), 44 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java index 3899c54e2..3b906b71f 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetDownloadTask.java @@ -30,9 +30,10 @@ import org.jackhuang.hmcl.util.Logging; import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.io.FileUtils; -import java.io.File; import java.io.IOException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -47,7 +48,7 @@ public final class GameAssetDownloadTask extends Task { private final AbstractDependencyManager dependencyManager; private final Version version; private final AssetIndexInfo assetIndexInfo; - private final File assetIndexFile; + private final Path assetIndexFile; private final boolean integrityCheck; private final List> dependents = new LinkedList<>(); private final List> dependencies = new LinkedList<>(); @@ -93,18 +94,18 @@ public final class GameAssetDownloadTask extends Task { if (isCancelled()) throw new InterruptedException(); - File file = dependencyManager.getGameRepository().getAssetObject(version.getId(), assetIndexInfo.getId(), assetObject); - boolean download = !file.isFile(); + Path file = dependencyManager.getGameRepository().getAssetObject(version.getId(), assetIndexInfo.getId(), assetObject); + boolean download = !Files.isRegularFile(file); try { - if (!download && integrityCheck && !assetObject.validateChecksum(file.toPath(), true)) + if (!download && integrityCheck && !assetObject.validateChecksum(file, true)) download = true; } catch (IOException e) { - Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + file.toPath(), e); + Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + file, e); } if (download) { List urls = dependencyManager.getDownloadProvider().getAssetObjectCandidates(assetObject.getLocation()); - FileDownloadTask task = new FileDownloadTask(urls, file, new FileDownloadTask.IntegrityCheck("SHA-1", assetObject.getHash())); + FileDownloadTask task = new FileDownloadTask(urls, file.toFile(), new FileDownloadTask.IntegrityCheck("SHA-1", assetObject.getHash())); task.setName(assetObject.getHash()); task.setCandidate(dependencyManager.getCacheRepository().getCommonDirectory() .resolve("assets").resolve("objects").resolve(assetObject.getLocation())); @@ -112,7 +113,7 @@ public final class GameAssetDownloadTask extends Task { task.setCaching(true); dependencies.add(task.withCounter("hmcl.install.assets")); } else { - dependencyManager.getCacheRepository().tryCacheFile(file.toPath(), CacheRepository.SHA1, assetObject.getHash()); + dependencyManager.getCacheRepository().tryCacheFile(file, CacheRepository.SHA1, assetObject.getHash()); } updateProgress(++progress, index.getObjects().size()); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java index b7c13a5bc..b6a3f84e6 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameAssetIndexDownloadTask.java @@ -30,8 +30,9 @@ import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.io.FileUtils; -import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; @@ -71,14 +72,14 @@ public final class GameAssetIndexDownloadTask extends Task { @Override public void execute() { AssetIndexInfo assetIndexInfo = version.getAssetIndex(); - File assetIndexFile = dependencyManager.getGameRepository().getIndexFile(version.getId(), assetIndexInfo.getId()); + Path assetIndexFile = dependencyManager.getGameRepository().getIndexFile(version.getId(), assetIndexInfo.getId()); boolean verifyHashCode = StringUtils.isNotBlank(assetIndexInfo.getSha1()) && assetIndexInfo.getUrl().contains(assetIndexInfo.getSha1()); - if (assetIndexFile.exists() && !forceDownloading) { + if (Files.exists(assetIndexFile) && !forceDownloading) { // verify correctness of file content if (verifyHashCode) { try { - String actualSum = Hex.encodeHex(DigestUtils.digest("SHA-1", assetIndexFile.toPath())); + String actualSum = Hex.encodeHex(DigestUtils.digest("SHA-1", assetIndexFile)); if (actualSum.equalsIgnoreCase(assetIndexInfo.getSha1())) return; } catch (IOException e) { @@ -98,7 +99,7 @@ public final class GameAssetIndexDownloadTask extends Task { // And Mojang will modify this file anytime. So assetIndex.hash might be outdated. FileDownloadTask task = new FileDownloadTask( dependencyManager.getDownloadProvider().injectURLWithCandidates(assetIndexInfo.getUrl()), - assetIndexFile, + assetIndexFile.toFile(), verifyHashCode ? new FileDownloadTask.IntegrityCheck("SHA-1", assetIndexInfo.getSha1()) : null ); task.setCacheRepository(dependencyManager.getCacheRepository()); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java index ce1f7ad4e..e4fb09577 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java @@ -382,7 +382,7 @@ public class DefaultGameRepository implements GameRepository { } @Override - public File getActualAssetDirectory(String version, String assetId) { + public Path getActualAssetDirectory(String version, String assetId) { try { return reconstructAssets(version, assetId); } catch (IOException | JsonParseException e) { @@ -392,14 +392,16 @@ public class DefaultGameRepository implements GameRepository { } @Override - public File getAssetDirectory(String version, String assetId) { - return new File(getBaseDirectory(), "assets"); + public Path getAssetDirectory(String version, String assetId) { + return getBaseDirectory().toPath().resolve("assets"); } @Override - public File getAssetObject(String version, String assetId, String name) throws IOException { + public Optional getAssetObject(String version, String assetId, String name) throws IOException { try { - return getAssetObject(version, assetId, getAssetIndex(version, assetId).getObjects().get(name)); + AssetObject assetObject = getAssetIndex(version, assetId).getObjects().get(name); + if (assetObject == null) return Optional.empty(); + return Optional.of(getAssetObject(version, assetId, assetObject)); } catch (IOException e) { throw e; } catch (Exception e) { @@ -408,30 +410,30 @@ public class DefaultGameRepository implements GameRepository { } @Override - public File getAssetObject(String version, String assetId, AssetObject obj) { + public Path getAssetObject(String version, String assetId, AssetObject obj) { return getAssetObject(version, getAssetDirectory(version, assetId), obj); } - public File getAssetObject(String version, File assetDir, AssetObject obj) { - return new File(assetDir, "objects/" + obj.getLocation()); + public Path getAssetObject(String version, Path assetDir, AssetObject obj) { + return assetDir.resolve("objects").resolve(obj.getLocation()); } @Override - public File getIndexFile(String version, String assetId) { - return new File(getAssetDirectory(version, assetId), "indexes/" + assetId + ".json"); + public Path getIndexFile(String version, String assetId) { + return getAssetDirectory(version, assetId).resolve("indexes").resolve(assetId + ".json"); } @Override - public File getLoggingObject(String version, String assetId, LoggingInfo loggingInfo) { - return new File(getAssetDirectory(version, assetId), "log_configs/" + loggingInfo.getFile().getId()); + public Path getLoggingObject(String version, String assetId, LoggingInfo loggingInfo) { + return getAssetDirectory(version, assetId).resolve("log_configs").resolve(loggingInfo.getFile().getId()); } - protected File reconstructAssets(String version, String assetId) throws IOException, JsonParseException { - File assetsDir = getAssetDirectory(version, assetId); - File indexFile = getIndexFile(version, assetId); - File virtualRoot = new File(new File(assetsDir, "virtual"), assetId); + protected Path reconstructAssets(String version, String assetId) throws IOException, JsonParseException { + Path assetsDir = getAssetDirectory(version, assetId); + Path indexFile = getIndexFile(version, assetId); + Path virtualRoot = assetsDir.resolve("virtual").resolve(assetId); - if (!indexFile.isFile()) + if (!Files.isRegularFile(indexFile)) return assetsDir; String assetIndexContent = FileUtils.readText(indexFile); @@ -444,11 +446,11 @@ public class DefaultGameRepository implements GameRepository { int cnt = 0; int tot = index.getObjects().entrySet().size(); for (Map.Entry entry : index.getObjects().entrySet()) { - File target = new File(virtualRoot, entry.getKey()); - File original = getAssetObject(version, assetsDir, entry.getValue()); - if (original.exists()) { + Path target = virtualRoot.resolve(entry.getKey()); + Path original = getAssetObject(version, assetsDir, entry.getValue()); + if (Files.exists(original)) { cnt++; - if (!target.isFile()) + if (!Files.isRegularFile(target)) FileUtils.copyFile(original, target); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java index 455cab482..6ddad8999 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameRepository.java @@ -22,6 +22,7 @@ import org.jackhuang.hmcl.util.platform.Platform; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -190,7 +191,7 @@ public interface GameRepository extends VersionProvider { * @param assetId the asset id, you can find it in {@link AssetIndexInfo#getId()} {@link Version#getAssetIndex()} * @return the actual asset directory */ - File getActualAssetDirectory(String version, String assetId); + Path getActualAssetDirectory(String version, String assetId); /** * Get the asset directory according to the asset id. @@ -199,7 +200,7 @@ public interface GameRepository extends VersionProvider { * @param assetId the asset id, you can find it in {@link AssetIndexInfo#getId()} {@link Version#getAssetIndex()} * @return the asset directory */ - File getAssetDirectory(String version, String assetId); + Path getAssetDirectory(String version, String assetId); /** * Get the file that given asset object refers to @@ -210,7 +211,7 @@ public interface GameRepository extends VersionProvider { * @throws java.io.IOException if I/O operation fails. * @return the file that given asset object refers to */ - File getAssetObject(String version, String assetId, String name) throws IOException; + Optional getAssetObject(String version, String assetId, String name) throws IOException; /** * Get the file that given asset object refers to @@ -220,7 +221,7 @@ public interface GameRepository extends VersionProvider { * @param obj the asset object, you can find it in {@link AssetIndex#getObjects()} * @return the file that given asset object refers to */ - File getAssetObject(String version, String assetId, AssetObject obj); + Path getAssetObject(String version, String assetId, AssetObject obj); /** * Get asset index that assetId represents @@ -237,7 +238,7 @@ public interface GameRepository extends VersionProvider { * @param version the id of specific version that is relevant to {@code assetId} * @param assetId the asset id, you can find it in {@link AssetIndexInfo#getId()} {@link Version#getAssetIndex()} */ - File getIndexFile(String version, String assetId); + Path getIndexFile(String version, String assetId); /** * Get logging object @@ -247,7 +248,7 @@ public interface GameRepository extends VersionProvider { * @param loggingInfo the logging info * @return the file that loggingInfo refers to */ - File getLoggingObject(String version, String assetId, LoggingInfo loggingInfo); + Path getLoggingObject(String version, String assetId, LoggingInfo loggingInfo); default List getClasspath(Version version) { List classpath = new ArrayList<>(); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java index cce1b341a..1248c2fd2 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java @@ -44,6 +44,7 @@ import java.net.Proxy; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.util.*; import java.util.function.Supplier; @@ -120,7 +121,10 @@ public class DefaultLauncher extends Launcher { if (OperatingSystem.CURRENT_OS == OperatingSystem.OSX) { res.addDefault("-Xdock:name=", "Minecraft " + version.getId()); - res.addDefault("-Xdock:icon=", repository.getAssetObject(version.getId(), version.getAssetIndex().getId(), "icons/minecraft.icns").getAbsolutePath()); + repository.getAssetObject(version.getId(), version.getAssetIndex().getId(), "icons/minecraft.icns") + .ifPresent(minecraftIcns -> { + res.addDefault("-Xdock:icon=", minecraftIcns.toAbsolutePath().toString()); + }); } if (OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS) @@ -201,12 +205,12 @@ public class DefaultLauncher extends Launcher { classpath.add(jar.getAbsolutePath()); // Provided Minecraft arguments - File gameAssets = repository.getActualAssetDirectory(version.getId(), version.getAssetIndex().getId()); + Path gameAssets = repository.getActualAssetDirectory(version.getId(), version.getAssetIndex().getId()); Map configuration = getConfigurations(); configuration.put("${classpath}", String.join(OperatingSystem.PATH_SEPARATOR, classpath)); configuration.put("${natives_directory}", nativeFolder.getAbsolutePath()); - configuration.put("${game_assets}", gameAssets.getAbsolutePath()); - configuration.put("${assets_root}", gameAssets.getAbsolutePath()); + configuration.put("${game_assets}", gameAssets.toAbsolutePath().toString()); + configuration.put("${assets_root}", gameAssets.toAbsolutePath().toString()); res.addAll(Arguments.parseArguments(version.getArguments().map(Arguments::getJvm).orElseGet(this::getDefaultJVMArguments), configuration)); if (authInfo.getArguments() != null && authInfo.getArguments().getJvm() != null && !authInfo.getArguments().getJvm().isEmpty())