fix: downloading libraries of optifine

This commit is contained in:
huanghongxun 2020-04-18 18:57:01 +08:00
parent 0639d82914
commit e630c6dff7
5 changed files with 96 additions and 51 deletions

View File

@ -126,26 +126,28 @@ public final class LauncherHelper {
DefaultDependencyManager dependencyManager = profile.getDependency();
Version version = MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion));
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
boolean integrityCheck = repository.unmarkVersionLaunchedAbnormally(selectedVersion);
TaskExecutor executor = Task.allOf(
Task.composeAsync(() -> {
if (setting.isNotCheckGame())
return null;
else
return dependencyManager.checkGameCompletionAsync(version, repository.unmarkVersionLaunchedAbnormally(selectedVersion));
}), Task.composeAsync(() -> {
try {
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
if ("Curse".equals(configuration.getType()))
return new CurseCompletionTask(dependencyManager, selectedVersion);
else if ("Server".equals(configuration.getType()))
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
else
return null;
} catch (IOException e) {
return null;
}
})).withStage("launch.state.dependencies")
TaskExecutor executor = dependencyManager.checkPatchCompletionAsync(repository.getVersion(selectedVersion), integrityCheck)
.thenComposeAsync(Task.allOf(
Task.composeAsync(() -> {
if (setting.isNotCheckGame())
return null;
else
return dependencyManager.checkGameCompletionAsync(version, integrityCheck);
}), Task.composeAsync(() -> {
try {
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
if ("Curse".equals(configuration.getType()))
return new CurseCompletionTask(dependencyManager, selectedVersion);
else if ("Server".equals(configuration.getType()))
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
else
return null;
} catch (IOException e) {
return null;
}
}))).withStage("launch.state.dependencies")
.thenComposeAsync(Task.supplyAsync(() -> {
try {
return account.logIn();

View File

@ -23,11 +23,18 @@ import org.jackhuang.hmcl.download.game.GameDownloadTask;
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
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.task.Task;
import java.io.IOException;
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.
@ -86,6 +93,28 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
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
public Task<Version> installLibraryAsync(String gameVersion, Version baseVersion, String libraryId, String libraryVersion) {
if (baseVersion.isResolved()) throw new IllegalArgumentException("Version should not be resolved");

View File

@ -56,6 +56,16 @@ public interface DependencyManager {
*/
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.
*/

View File

@ -91,10 +91,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
List<Library> libraries = new ArrayList<>();
for (Library library : version.getLibraries()) {
String groupId = library.getGroupId();
String artifactId = library.getArtifactId();
if (type.group.matcher(groupId).matches() && type.artifact.matcher(artifactId).matches()) {
if (type.matchLibrary(library)) {
// skip
} else {
libraries.add(library);
@ -129,11 +126,8 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
Map<String, Pair<Library, String>> libraries = new HashMap<>();
for (Library library : version.resolve(null).getLibraries()) {
String groupId = library.getGroupId();
String artifactId = library.getArtifactId();
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()));
break;
}
@ -180,6 +174,10 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
return type;
return null;
}
public boolean matchLibrary(Library library) {
return group.matcher(library.getGroupId()).matches() && artifact.matcher(library.getArtifactId()).matches();
}
}
public static class LibraryMark {

View File

@ -18,8 +18,10 @@
package org.jackhuang.hmcl.download.game;
import org.jackhuang.hmcl.download.AbstractDependencyManager;
import org.jackhuang.hmcl.game.GameRepository;
import org.jackhuang.hmcl.game.Library;
import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.io.FileUtils;
@ -29,7 +31,6 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarFile;
import java.util.logging.Level;
/**
@ -76,33 +77,38 @@ public final class GameLibrariesTask extends Task<Void> {
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
public void execute() {
libraries.stream().filter(Library::appliesToCurrentEnvironment).forEach(library -> {
File file = dependencyManager.getGameRepository().getLibraryFile(version, library);
Path jar = file.toPath();
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) {
if (shouldDownloadLibrary(dependencyManager.getGameRepository(), version, library, integrityCheck)) {
dependencies.add(new LibraryDownloadTask(dependencyManager, file, library));
} else {
dependencyManager.getCacheRepository().tryCacheLibrary(library, file.toPath());