fix: downloading libraries of optifine
This commit is contained in:
@@ -126,26 +126,28 @@ public final class LauncherHelper {
|
|||||||
DefaultDependencyManager dependencyManager = profile.getDependency();
|
DefaultDependencyManager dependencyManager = profile.getDependency();
|
||||||
Version version = MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion));
|
Version version = MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion));
|
||||||
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
||||||
|
boolean integrityCheck = repository.unmarkVersionLaunchedAbnormally(selectedVersion);
|
||||||
|
|
||||||
TaskExecutor executor = Task.allOf(
|
TaskExecutor executor = dependencyManager.checkPatchCompletionAsync(repository.getVersion(selectedVersion), integrityCheck)
|
||||||
Task.composeAsync(() -> {
|
.thenComposeAsync(Task.allOf(
|
||||||
if (setting.isNotCheckGame())
|
Task.composeAsync(() -> {
|
||||||
return null;
|
if (setting.isNotCheckGame())
|
||||||
else
|
return null;
|
||||||
return dependencyManager.checkGameCompletionAsync(version, repository.unmarkVersionLaunchedAbnormally(selectedVersion));
|
else
|
||||||
}), Task.composeAsync(() -> {
|
return dependencyManager.checkGameCompletionAsync(version, integrityCheck);
|
||||||
try {
|
}), Task.composeAsync(() -> {
|
||||||
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
|
try {
|
||||||
if ("Curse".equals(configuration.getType()))
|
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
|
||||||
return new CurseCompletionTask(dependencyManager, selectedVersion);
|
if ("Curse".equals(configuration.getType()))
|
||||||
else if ("Server".equals(configuration.getType()))
|
return new CurseCompletionTask(dependencyManager, selectedVersion);
|
||||||
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
|
else if ("Server".equals(configuration.getType()))
|
||||||
else
|
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
|
||||||
return null;
|
else
|
||||||
} catch (IOException e) {
|
return null;
|
||||||
return null;
|
} catch (IOException e) {
|
||||||
}
|
return null;
|
||||||
})).withStage("launch.state.dependencies")
|
}
|
||||||
|
}))).withStage("launch.state.dependencies")
|
||||||
.thenComposeAsync(Task.supplyAsync(() -> {
|
.thenComposeAsync(Task.supplyAsync(() -> {
|
||||||
try {
|
try {
|
||||||
return account.logIn();
|
return account.logIn();
|
||||||
|
|||||||
@@ -23,11 +23,18 @@ import org.jackhuang.hmcl.download.game.GameDownloadTask;
|
|||||||
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
||||||
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
|
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
|
||||||
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
||||||
|
import org.jackhuang.hmcl.game.GameVersion;
|
||||||
|
import org.jackhuang.hmcl.game.Library;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.OPTIFINE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: This class has no state.
|
* Note: This class has no state.
|
||||||
@@ -86,6 +93,28 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
|||||||
return new GameLibrariesTask(this, version, integrityCheck, version.getLibraries());
|
return new GameLibrariesTask(this, version, integrityCheck, version.getLibraries());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Task<?> checkPatchCompletionAsync(Version version, boolean integrityCheck) {
|
||||||
|
return Task.composeAsync(() -> {
|
||||||
|
List<Task<?>> tasks = new ArrayList<>();
|
||||||
|
|
||||||
|
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
||||||
|
if (!gameVersion.isPresent()) return null;
|
||||||
|
|
||||||
|
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version.resolvePreservingPatches(getGameRepository()));
|
||||||
|
version.resolve(getGameRepository()).getLibraries().stream().filter(Library::appliesToCurrentEnvironment).forEach(library -> {
|
||||||
|
Optional<String> libraryVersion = analyzer.getVersion(OPTIFINE);
|
||||||
|
if (OPTIFINE.matchLibrary(library) && libraryVersion.isPresent()) {
|
||||||
|
if (GameLibrariesTask.shouldDownloadLibrary(repository, version, library, integrityCheck)) {
|
||||||
|
tasks.add(installLibraryAsync(gameVersion.get(), version, OPTIFINE.getPatchId(), libraryVersion.get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Task.allOf(tasks);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task<Version> installLibraryAsync(String gameVersion, Version baseVersion, String libraryId, String libraryVersion) {
|
public Task<Version> installLibraryAsync(String gameVersion, Version baseVersion, String libraryId, String libraryVersion) {
|
||||||
if (baseVersion.isResolved()) throw new IllegalArgumentException("Version should not be resolved");
|
if (baseVersion.isResolved()) throw new IllegalArgumentException("Version should not be resolved");
|
||||||
|
|||||||
@@ -56,6 +56,16 @@ public interface DependencyManager {
|
|||||||
*/
|
*/
|
||||||
Task<?> checkLibraryCompletionAsync(Version version, boolean integrityCheck);
|
Task<?> checkLibraryCompletionAsync(Version version, boolean integrityCheck);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if patches of this version in complete.
|
||||||
|
* If not, reinstall the patch if possible.
|
||||||
|
*
|
||||||
|
* @param version the version to be checked
|
||||||
|
* @param integrityCheck check if some libraries are corrupt.
|
||||||
|
* @return the task to check patches completion.
|
||||||
|
*/
|
||||||
|
Task<?> checkPatchCompletionAsync(Version version, boolean integrityCheck);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The builder to build a brand new game then libraries such as Forge, LiteLoader and OptiFine.
|
* The builder to build a brand new game then libraries such as Forge, LiteLoader and OptiFine.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -91,10 +91,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
|||||||
|
|
||||||
List<Library> libraries = new ArrayList<>();
|
List<Library> libraries = new ArrayList<>();
|
||||||
for (Library library : version.getLibraries()) {
|
for (Library library : version.getLibraries()) {
|
||||||
String groupId = library.getGroupId();
|
if (type.matchLibrary(library)) {
|
||||||
String artifactId = library.getArtifactId();
|
|
||||||
|
|
||||||
if (type.group.matcher(groupId).matches() && type.artifact.matcher(artifactId).matches()) {
|
|
||||||
// skip
|
// skip
|
||||||
} else {
|
} else {
|
||||||
libraries.add(library);
|
libraries.add(library);
|
||||||
@@ -129,11 +126,8 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
|||||||
Map<String, Pair<Library, String>> libraries = new HashMap<>();
|
Map<String, Pair<Library, String>> libraries = new HashMap<>();
|
||||||
|
|
||||||
for (Library library : version.resolve(null).getLibraries()) {
|
for (Library library : version.resolve(null).getLibraries()) {
|
||||||
String groupId = library.getGroupId();
|
|
||||||
String artifactId = library.getArtifactId();
|
|
||||||
|
|
||||||
for (LibraryType type : LibraryType.values()) {
|
for (LibraryType type : LibraryType.values()) {
|
||||||
if (type.group.matcher(groupId).matches() && type.artifact.matcher(artifactId).matches()) {
|
if (type.matchLibrary(library)) {
|
||||||
libraries.put(type.getPatchId(), pair(library, library.getVersion()));
|
libraries.put(type.getPatchId(), pair(library, library.getVersion()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -180,6 +174,10 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
|||||||
return type;
|
return type;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean matchLibrary(Library library) {
|
||||||
|
return group.matcher(library.getGroupId()).matches() && artifact.matcher(library.getArtifactId()).matches();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LibraryMark {
|
public static class LibraryMark {
|
||||||
|
|||||||
@@ -18,8 +18,10 @@
|
|||||||
package org.jackhuang.hmcl.download.game;
|
package org.jackhuang.hmcl.download.game;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.download.AbstractDependencyManager;
|
import org.jackhuang.hmcl.download.AbstractDependencyManager;
|
||||||
|
import org.jackhuang.hmcl.game.GameRepository;
|
||||||
import org.jackhuang.hmcl.game.Library;
|
import org.jackhuang.hmcl.game.Library;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
@@ -29,7 +31,6 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.jar.JarFile;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,33 +77,38 @@ public final class GameLibrariesTask extends Task<Void> {
|
|||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean shouldDownloadLibrary(GameRepository gameRepository, Version version, Library library, boolean integrityCheck) {
|
||||||
|
File file = gameRepository.getLibraryFile(version, library);
|
||||||
|
Path jar = file.toPath();
|
||||||
|
if (!file.isFile()) return true;
|
||||||
|
try {
|
||||||
|
if (integrityCheck && !library.getDownload().validateChecksum(jar, true)) return true;
|
||||||
|
if (integrityCheck &&
|
||||||
|
library.getChecksums() != null && !library.getChecksums().isEmpty() &&
|
||||||
|
!LibraryDownloadTask.checksumValid(file, library.getChecksums())) return true;
|
||||||
|
if (integrityCheck) {
|
||||||
|
String ext = FileUtils.getExtension(file);
|
||||||
|
if (ext.equals("jar")) {
|
||||||
|
try {
|
||||||
|
FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER.checkIntegrity(jar, jar);
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
// the Jar file is malformed, so re-download it.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + jar, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
libraries.stream().filter(Library::appliesToCurrentEnvironment).forEach(library -> {
|
libraries.stream().filter(Library::appliesToCurrentEnvironment).forEach(library -> {
|
||||||
File file = dependencyManager.getGameRepository().getLibraryFile(version, library);
|
File file = dependencyManager.getGameRepository().getLibraryFile(version, library);
|
||||||
Path jar = file.toPath();
|
if (shouldDownloadLibrary(dependencyManager.getGameRepository(), version, library, integrityCheck)) {
|
||||||
boolean download = !file.isFile();
|
|
||||||
try {
|
|
||||||
if (!download && integrityCheck && !library.getDownload().validateChecksum(jar, true)) download = true;
|
|
||||||
if (!download && integrityCheck &&
|
|
||||||
library.getChecksums() != null && !library.getChecksums().isEmpty() &&
|
|
||||||
!LibraryDownloadTask.checksumValid(file, library.getChecksums())) download = true;
|
|
||||||
if (!download && integrityCheck) {
|
|
||||||
String ext = FileUtils.getExtension(file);
|
|
||||||
if (ext.equals("jar")) {
|
|
||||||
try (JarFile jarFile = new JarFile(file)) {
|
|
||||||
jarFile.getManifest();
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
// the Jar file is malformed, so re-download it.
|
|
||||||
download = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + jar, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (download) {
|
|
||||||
dependencies.add(new LibraryDownloadTask(dependencyManager, file, library));
|
dependencies.add(new LibraryDownloadTask(dependencyManager, file, library));
|
||||||
} else {
|
} else {
|
||||||
dependencyManager.getCacheRepository().tryCacheLibrary(library, file.toPath());
|
dependencyManager.getCacheRepository().tryCacheLibrary(library, file.toPath());
|
||||||
|
|||||||
Reference in New Issue
Block a user