feat: cache detected game version

This commit is contained in:
huanghongxun
2021-08-21 14:41:56 +08:00
parent ddd0f83936
commit 7da9d0f283
13 changed files with 62 additions and 28 deletions

View File

@@ -23,7 +23,6 @@ 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;
@@ -99,7 +98,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
return Task.composeAsync(() -> {
List<Task<?>> tasks = new ArrayList<>();
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
Optional<String> gameVersion = repository.getGameVersion(version);
if (!gameVersion.isPresent()) return null;
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version.resolvePreservingPatches(getGameRepository()));

View File

@@ -29,6 +29,8 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.Pair.pair;
import static org.jackhuang.hmcl.util.StringUtils.removePrefix;
import static org.jackhuang.hmcl.util.StringUtils.removeSuffix;
public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMark> {
private Version version;
@@ -153,6 +155,10 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
return mainClass != null && (LAUNCH_WRAPPER_MAIN.equals(mainClass) || mainClass.startsWith("net.fabricmc") || mainClass.startsWith("cpw.mods"));
}
public static String modifyVersion(String gameVersion, String version) {
return removeSuffix(removePrefix(removeSuffix(removePrefix(version.replace(gameVersion, "").trim(), "-"), "-"), "_"), "_");
}
public enum LibraryType {
MINECRAFT(true, "game", Pattern.compile("^$"), Pattern.compile("^$")),
FABRIC(true, "fabric", Pattern.compile("net\\.fabricmc"), Pattern.compile("fabric-loader")),

View File

@@ -22,7 +22,6 @@ import org.jackhuang.hmcl.download.DependencyManager;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.download.VersionMismatchException;
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
import org.jackhuang.hmcl.game.GameVersion;
import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Task;
@@ -132,7 +131,7 @@ public final class ForgeInstallTask extends Task<Version> {
* @throws VersionMismatchException if required game version of installer does not match the actual one.
*/
public static boolean detectForgeInstallerType(DependencyManager dependencyManager, Version version, Path installer) throws IOException, VersionMismatchException {
Optional<String> gameVersion = GameVersion.minecraftVersion(dependencyManager.getGameRepository().getVersionJar(version));
Optional<String> gameVersion = dependencyManager.getGameRepository().getGameVersion(version);
if (!gameVersion.isPresent()) throw new IOException();
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
String installProfileText = FileUtils.readText(fs.getPath("install_profile.json"));
@@ -165,7 +164,7 @@ public final class ForgeInstallTask extends Task<Version> {
* @throws VersionMismatchException if required game version of installer does not match the actual one.
*/
public static Task<Version> install(DefaultDependencyManager dependencyManager, Version version, Path installer) throws IOException, VersionMismatchException {
Optional<String> gameVersion = GameVersion.minecraftVersion(dependencyManager.getGameRepository().getVersionJar(version));
Optional<String> gameVersion = dependencyManager.getGameRepository().getGameVersion(version);
if (!gameVersion.isPresent()) throw new IOException();
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
String installProfileText = FileUtils.readText(fs.getPath("install_profile.json"));

View File

@@ -208,8 +208,7 @@ public final class OptiFineInstallTask extends Task<Version> {
* @throws VersionMismatchException if required game version of installer does not match the actual one.
*/
public static Task<Version> install(DefaultDependencyManager dependencyManager, Version version, Path installer) throws IOException, VersionMismatchException {
File jar = dependencyManager.getGameRepository().getVersionJar(version);
Optional<String> gameVersion = GameVersion.minecraftVersion(jar);
Optional<String> gameVersion = dependencyManager.getGameRepository().getGameVersion(version);
if (!gameVersion.isPresent()) throw new IOException();
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
Path configClass = fs.getPath("Config.class");

View File

@@ -50,6 +50,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.stream.Stream;
@@ -64,6 +65,7 @@ public class DefaultGameRepository implements GameRepository {
private File baseDirectory;
protected Map<String, Version> versions;
private ConcurrentHashMap<File, Optional<String>> gameVersions = new ConcurrentHashMap<>();
public DefaultGameRepository(File baseDirectory) {
this.baseDirectory = baseDirectory;
@@ -136,6 +138,21 @@ public class DefaultGameRepository implements GameRepository {
return new File(getVersionRoot(id), id + ".jar");
}
@Override
public Optional<String> getGameVersion(Version version) {
// This implementation may cause multiple flows against the same version entering
// this function, which is accepted because GameVersion::minecraftVersion should
// be consistent.
File versionJar = getVersionJar(version);
if (gameVersions.containsKey(versionJar)) {
return gameVersions.get(versionJar);
} else {
Optional<String> gameVersion = GameVersion.minecraftVersion(versionJar);
gameVersions.put(versionJar, gameVersion);
return gameVersion;
}
}
@Override
public File getNativeDirectory(String id) {
return new File(getVersionRoot(id), "natives");
@@ -321,6 +338,7 @@ public class DefaultGameRepository implements GameRepository {
}
}
this.gameVersions.clear();
this.versions = versions;
}

View File

@@ -24,6 +24,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
/**
* Supports operations on versioning.
@@ -134,6 +135,30 @@ public interface GameRepository extends VersionProvider {
*/
File getVersionJar(Version version);
/**
* Detect game version.
*
* This method is time-consuming, but the result will be cached.
* Consider running this job in IO scheduler.
*
* @param version version
* @return game version, or empty if an error occurred in detection.
*/
Optional<String> getGameVersion(Version version);
/**
* Detect game version.
*
* This method is time-consuming, but the result will be cached.
* Consider running this job in IO scheduler.
*
* @param versionId id of version
* @return game version, or empty if an error occurred in detection.
*/
default Optional<String> getGameVersion(String versionId) throws VersionNotFoundException {
return getGameVersion(getVersion(versionId));
}
/**
* Get minecraft jar
*

View File

@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.mod.mcbbs;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.game.GameVersion;
import org.jackhuang.hmcl.game.Library;
import org.jackhuang.hmcl.mod.ModAdviser;
import org.jackhuang.hmcl.mod.Modpack;
@@ -81,7 +80,7 @@ public class McbbsModpackExportTask extends Task<Void> {
});
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(repository.getResolvedPreservingPatchesVersion(version));
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version))
String gameVersion = repository.getGameVersion(version)
.orElseThrow(() -> new IOException("Cannot parse the version of " + version));
List<McbbsModpackManifest.Addon> addons = new ArrayList<>();

View File

@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.mod.multimc;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.game.GameVersion;
import org.jackhuang.hmcl.mod.ModAdviser;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.ModpackExportInfo;
@@ -72,7 +71,7 @@ public class MultiMCModpackExportTask extends Task<Void> {
zip.putDirectory(repository.getRunDirectory(versionId).toPath(), ".minecraft", path -> Modpack.acceptFile(path, blackList, whitelist));
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(repository.getResolvedPreservingPatchesVersion(versionId));
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(versionId))
String gameVersion = repository.getGameVersion(versionId)
.orElseThrow(() -> new IOException("Cannot parse the version of " + versionId));
List<MultiMCManifest.MultiMCManifestComponent> components = new ArrayList<>();
components.add(new MultiMCManifest.MultiMCManifestComponent(true, false, "net.minecraft", gameVersion));

View File

@@ -19,7 +19,6 @@ package org.jackhuang.hmcl.mod.server;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.game.GameVersion;
import org.jackhuang.hmcl.mod.ModAdviser;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.ModpackConfiguration;
@@ -81,7 +80,7 @@ public class ServerModpackExportTask extends Task<Void> {
});
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(repository.getResolvedPreservingPatchesVersion(versionId));
String gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(versionId))
String gameVersion = repository.getGameVersion(versionId)
.orElseThrow(() -> new IOException("Cannot parse the version of " + versionId));
List<ServerModpackManifest.Addon> addons = new ArrayList<>();
addons.add(new ServerModpackManifest.Addon(MINECRAFT.getPatchId(), gameVersion));