-
Notifications
You must be signed in to change notification settings - Fork 920
perf(download): skip re-installing loader if identical version patch … #6594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
f66592e
fd56d5c
f351e1c
35344ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,9 +27,11 @@ | |
| import org.jackhuang.hmcl.game.Artifact; | ||
| import org.jackhuang.hmcl.game.DefaultGameRepository; | ||
| import org.jackhuang.hmcl.game.GameInstanceManifest; | ||
| import org.jackhuang.hmcl.game.GameInstancePatch; | ||
| import org.jackhuang.hmcl.game.Library; | ||
| import org.jackhuang.hmcl.task.Task; | ||
| import org.jackhuang.hmcl.util.io.FileUtils; | ||
| import org.jetbrains.annotations.Nullable; | ||
|
|
||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
|
|
@@ -155,8 +157,75 @@ public Task<GameInstanceManifest> installLibraryAsync(String gameVersion, GameIn | |
| .withStage(String.format("hmcl.install.%s:%s", libraryId, libraryVersion)); | ||
| } | ||
|
|
||
| /// Checks whether a resolved [Library] belongs to the given loader type. | ||
| /// | ||
| /// The mapping must stay consistent with [LibraryAnalyzer.LibraryType]'s | ||
| /// group-id patterns so that the file-integrity check covers the correct jars. | ||
| /// | ||
| /// @param library a library entry from the resolved launch manifest | ||
| /// @param libraryId the patch id of the loader (e.g. `"forge"`, `"fabric"`) | ||
| /// @return `true` if the library's groupId matches the loader | ||
| private static boolean isLoaderLibrary(Library library, String libraryId) { | ||
| if (library == null || library.groupId() == null) return false; | ||
| String groupId = library.groupId().toLowerCase(java.util.Locale.ROOT); | ||
| String targetId = libraryId.toLowerCase(java.util.Locale.ROOT); | ||
| return switch (targetId) { | ||
| case "forge" -> groupId.startsWith("net.minecraftforge"); | ||
| case "neoforge" -> groupId.startsWith("net.neoforged"); | ||
| case "optifine" -> "optifine".equals(groupId) || "net.optifine".equals(groupId); | ||
| case "fabric" -> groupId.startsWith("net.fabricmc"); | ||
| case "quilt" -> groupId.startsWith("org.quiltmc"); | ||
| case "legacyfabric" -> groupId.startsWith("net.legacyfabric") || groupId.startsWith("net.fabricmc"); | ||
| case "liteloader" -> "com.mumfrey".equals(groupId); | ||
| case "cleanroom" -> groupId.startsWith("com.cleanroommc") || groupId.startsWith("zone.rong"); | ||
| default -> groupId.contains(targetId); | ||
| }; | ||
| } | ||
|
|
||
| /// Checks if a matching library patch is already installed for the target instance on disk and intact. | ||
| /// | ||
| /// @param baseVersion the base game instance manifest | ||
| /// @param libraryVersion the remote library version to install | ||
| /// @return the existing intact matching patch, or `null` if the library is not installed, version mismatches, or files need repair | ||
| private @Nullable GameInstancePatch getIntactMatchingPatch(GameInstanceManifest baseVersion, RemoteVersion libraryVersion) { | ||
| if (LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId().equals(libraryVersion.getLibraryId()) || !repository.hasInstance(baseVersion.id())) { | ||
| return null; | ||
| } | ||
|
|
||
| try { | ||
| GameInstanceManifest existingManifest = repository.getInstanceManifest(baseVersion.id()); | ||
| String currentGameVersion = repository.getGameVersion(existingManifest).orElse(null); | ||
| if (!java.util.Objects.equals(currentGameVersion, libraryVersion.getGameVersion())) { | ||
|
fatelove42 marked this conversation as resolved.
|
||
| return null; | ||
| } | ||
|
|
||
| GameInstancePatch matchingPatch = existingManifest.getPatches().stream() | ||
| .filter(patch -> libraryVersion.getLibraryId().equals(patch.id()) | ||
| && java.util.Objects.equals(patch.version(), libraryVersion.getSelfVersion())) | ||
| .findFirst() | ||
| .orElse(null); | ||
| if (matchingPatch == null) { | ||
| return null; | ||
| } | ||
|
|
||
| GameInstanceManifest.Resolved resolved = repository.getResolvedInstanceManifest(baseVersion.id()); | ||
| boolean needsRepair = resolved.launchManifest().getLibraries().stream() | ||
| .filter(lib -> isLoaderLibrary(lib, libraryVersion.getLibraryId())) | ||
| .anyMatch(lib -> GameLibrariesTask.shouldDownloadLibrary(repository, existingManifest, lib, true)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When rebuilding an existing instance with the same Minecraft version, Useful? React with 👍 / 👎.
fatelove42 marked this conversation as resolved.
Outdated
|
||
|
|
||
| return needsRepair ? null : matchingPatch; | ||
| } catch (Exception ignored) { | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public Task<GameInstanceManifest> installLibraryAsync(GameInstanceManifest baseVersion, RemoteVersion libraryVersion) { | ||
| GameInstancePatch matchingPatch = getIntactMatchingPatch(baseVersion, libraryVersion); | ||
| if (matchingPatch != null) { | ||
| return Task.completed(baseVersion.addPatch(matchingPatch)); | ||
| } | ||
|
|
||
| AtomicReference<GameInstanceManifest> removedLibraryVersion = new AtomicReference<>(); | ||
|
|
||
| return removeLibraryAsync(baseVersion, libraryVersion.getLibraryId()) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.