mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-12 21:36:21 -04:00
feat: cache detected game version
This commit is contained in:
parent
ddd0f83936
commit
7da9d0f283
@ -133,7 +133,7 @@ public final class LauncherHelper {
|
||||
HMCLGameRepository repository = profile.getRepository();
|
||||
DefaultDependencyManager dependencyManager = profile.getDependency();
|
||||
Version version = MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion));
|
||||
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
||||
Optional<String> gameVersion = repository.getGameVersion(version);
|
||||
boolean integrityCheck = repository.unmarkVersionLaunchedAbnormally(selectedVersion);
|
||||
CountDownLatch launchingLatch = new CountDownLatch(1);
|
||||
|
||||
@ -311,7 +311,7 @@ public final class LauncherHelper {
|
||||
|
||||
// Without onAccept called, the launching operation will be terminated.
|
||||
|
||||
VersionNumber gameVersion = VersionNumber.asVersion(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)).orElse("Unknown"));
|
||||
VersionNumber gameVersion = VersionNumber.asVersion(profile.getRepository().getGameVersion(version).orElse("Unknown"));
|
||||
JavaVersion java = setting.getJavaVersion();
|
||||
if (java == null) {
|
||||
Controllers.dialog(i18n("launch.wrong_javadir"), i18n("message.warning"), MessageType.WARNING, onAccept);
|
||||
|
@ -26,7 +26,6 @@ import javafx.scene.control.Control;
|
||||
import javafx.scene.control.Skin;
|
||||
import javafx.scene.image.Image;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.mod.ModpackConfiguration;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
@ -41,8 +40,6 @@ import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.MINECRAFT;
|
||||
import static org.jackhuang.hmcl.util.Lang.handleUncaught;
|
||||
import static org.jackhuang.hmcl.util.Lang.threadPool;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.StringUtils.removePrefix;
|
||||
import static org.jackhuang.hmcl.util.StringUtils.removeSuffix;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class GameItem extends Control {
|
||||
@ -61,7 +58,7 @@ public class GameItem extends Control {
|
||||
this.version = id;
|
||||
|
||||
// GameVersion.minecraftVersion() is a time-costing job (up to ~200 ms)
|
||||
CompletableFuture.supplyAsync(() -> GameVersion.minecraftVersion(profile.getRepository().getVersionJar(id)).orElse(i18n("message.unknown")), POOL_VERSION_RESOLVE)
|
||||
CompletableFuture.supplyAsync(() -> profile.getRepository().getGameVersion(id).orElse(i18n("message.unknown")), POOL_VERSION_RESOLVE)
|
||||
.thenAcceptAsync(game -> {
|
||||
StringBuilder libraries = new StringBuilder(game);
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(id));
|
||||
@ -72,7 +69,7 @@ public class GameItem extends Control {
|
||||
if (I18n.hasKey("install.installer." + libraryId)) {
|
||||
libraries.append(", ").append(i18n("install.installer." + libraryId));
|
||||
if (libraryVersion != null)
|
||||
libraries.append(": ").append(modifyVersion("", libraryVersion.replaceAll("(?i)" + libraryId, "")));
|
||||
libraries.append(": ").append(LibraryAnalyzer.modifyVersion(game, libraryVersion.replaceAll("(?i)" + libraryId, "")));
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,8 +120,4 @@ public class GameItem extends Control {
|
||||
public ObjectProperty<Image> imageProperty() {
|
||||
return image;
|
||||
}
|
||||
|
||||
private static String modifyVersion(String gameVersion, String version) {
|
||||
return removeSuffix(removePrefix(removeSuffix(removePrefix(version.replace(gameVersion, "").trim(), "-"), "-"), "_"), "_");
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import javafx.scene.Node;
|
||||
import javafx.scene.control.Skin;
|
||||
import javafx.stage.FileChooser;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
@ -70,7 +69,7 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
|
||||
this.gameVersion = null;
|
||||
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)).orElse(null);
|
||||
gameVersion = profile.getRepository().getGameVersion(version).orElse(null);
|
||||
|
||||
return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId));
|
||||
}).thenAcceptAsync(analyzer -> {
|
||||
|
@ -23,7 +23,6 @@ import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.Node;
|
||||
import javafx.stage.FileChooser;
|
||||
import org.jackhuang.hmcl.game.GameVersion;
|
||||
import org.jackhuang.hmcl.game.World;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Theme;
|
||||
@ -87,7 +86,7 @@ public class WorldListPage extends ListPageBase<WorldListItem> implements Versio
|
||||
|
||||
setLoading(true);
|
||||
return CompletableFuture
|
||||
.runAsync(() -> gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(id)).orElse(null))
|
||||
.runAsync(() -> gameVersion = profile.getRepository().getGameVersion(id).orElse(null))
|
||||
.thenApplyAsync(unused -> {
|
||||
try (Stream<World> stream = World.getWorlds(savesDir)) {
|
||||
return stream.parallel().collect(Collectors.toList());
|
||||
|
@ -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()));
|
||||
|
@ -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")),
|
||||
|
@ -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"));
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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<>();
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user