mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2024-11-27 06:10:08 +08:00
fix(launch): cannot launch far old versions on macOS.
This commit is contained in:
parent
a4f22671c6
commit
f70ec8a090
@ -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<Void> {
|
||||
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<Task<?>> dependents = new LinkedList<>();
|
||||
private final List<Task<?>> dependencies = new LinkedList<>();
|
||||
@ -93,18 +94,18 @@ public final class GameAssetDownloadTask extends Task<Void> {
|
||||
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<URL> 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<Void> {
|
||||
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());
|
||||
|
@ -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<Void> {
|
||||
@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<Void> {
|
||||
// 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());
|
||||
|
@ -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<Path> 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<String, AssetObject> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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<Path> 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<String> getClasspath(Version version) {
|
||||
List<String> classpath = new ArrayList<>();
|
||||
|
@ -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<String, String> 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())
|
||||
|
Loading…
Reference in New Issue
Block a user