diff --git a/.gitignore b/.gitignore index 082849356..b5fe10e98 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ hs_err_pid* NVIDIA minecraft-exported-crash-info* hmcl-exported-logs-* +/.java/ # gradle build /build/ diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java index 44729a983..77a347b61 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java @@ -83,6 +83,7 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider { pair("https://repo1.maven.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"), pair("https://repo.maven.apache.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"), pair("https://hmcl-dev.github.io/metadata/cleanroom", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/cleanroom"), + pair("https://hmcl-dev.github.io/metadata/fmllibs", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/fmllibs"), pair("https://zkitefly.github.io/unlisted-versions-of-minecraft", "https://alist.8mi.tech/d/mirror/unlisted-versions-of-minecraft/Auto") // // https://github.com/mcmod-info-mirror/mcim-rust-api // pair("https://api.modrinth.com", "https://mod.mcimirror.top/modrinth"), diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java index f8ca81e78..1bd25c60a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameLibrariesTask.java @@ -19,18 +19,22 @@ package org.jackhuang.hmcl.download.game; import org.jackhuang.hmcl.download.AbstractDependencyManager; import org.jackhuang.hmcl.download.LibraryAnalyzer; +import org.jackhuang.hmcl.game.DefaultGameRepository; 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.DigestUtils; import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.versioning.GameVersionNumber; import org.jackhuang.hmcl.util.versioning.VersionNumber; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; +import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; @@ -114,6 +118,18 @@ public final class GameLibrariesTask extends Task { return false; } + private static boolean shouldDownloadFMLLib(FMLLib fmlLib, Path file) { + if (!Files.isRegularFile(file)) + return true; + + try { + return !DigestUtils.digestToString("SHA-1", file).equalsIgnoreCase(fmlLib.sha1); + } catch (IOException e) { + LOG.warning("Unable to calc hash value of file " + file, e); + return true; + } + } + @Override public void execute() throws IOException { int progress = 0; @@ -123,6 +139,27 @@ public final class GameLibrariesTask extends Task { continue; } + // https://github.com/HMCL-dev/HMCL/issues/3975 + if ("net.minecraftforge".equals(library.getGroupId()) && "minecraftforge".equals(library.getArtifactId()) + && gameRepository instanceof DefaultGameRepository defaultGameRepository) { + List fmlLibs = getFMLLibs(library.getVersion()); + if (fmlLibs != null) { + Path libDir = defaultGameRepository.getBaseDirectory().toPath() + .resolve("lib") + .toAbsolutePath().normalize(); + + for (FMLLib fmlLib : fmlLibs) { + Path file = libDir.resolve(fmlLib.name); + if (shouldDownloadFMLLib(fmlLib, file)) { + List uris = dependencyManager.getDownloadProvider() + .injectURLWithCandidates(fmlLib.getDownloadURI()); + dependencies.add(new FileDownloadTask(uris, file) + .withCounter("hmcl.install.libraries")); + } + } + } + } + File file = gameRepository.getLibraryFile(version, library); if ("optifine".equals(library.getGroupId()) && file.exists() && GameVersionNumber.asGameVersion(gameRepository.getGameVersion(version)).compareTo("1.20.4") == 0) { String forgeVersion = LibraryAnalyzer.analyze(version, "1.20.4") @@ -151,4 +188,28 @@ public final class GameLibrariesTask extends Task { } } + private static @Nullable List getFMLLibs(String forgeVersion) { + if (forgeVersion == null) + return null; + + // Minecraft 1.5.2 + if (forgeVersion.startsWith("7.8.1.")) { + return List.of( + new FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"), + new FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"), + new FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"), + new FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"), + new FMLLib("deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9"), + new FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85") + ); + } + + return null; + } + + private record FMLLib(String name, String sha1) { + public String getDownloadURI() { + return "https://hmcl-dev.github.io/metadata/fmllibs/" + name; + } + } }