From 139fb41149cc7596c73be5b130f2fb8dda3d071d Mon Sep 17 00:00:00 2001 From: Burning_TNT Date: Sat, 12 Apr 2025 12:07:26 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20#3147:=20=E4=BF=AE=E5=A4=8D=20LiteLoader?= =?UTF-8?q?=20=E4=B8=8B=E8=BD=BD=E7=9B=B8=E5=85=B3=E9=97=AE=E9=A2=98=20(#3?= =?UTF-8?q?776)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #3147 * Fix: Use 'release' classifier on snapshot versions. Speed up loading time. * Use https. --- .../liteloader/LiteLoaderBMCLVersionList.java | 81 ++++-------- .../liteloader/LiteLoaderRemoteVersion.java | 5 +- .../liteloader/LiteLoaderVersionList.java | 116 ++++++++++-------- 3 files changed, 93 insertions(+), 109 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderBMCLVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderBMCLVersionList.java index 229d47a6d..8ede1acce 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderBMCLVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderBMCLVersionList.java @@ -18,21 +18,16 @@ package org.jackhuang.hmcl.download.liteloader; import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider; +import org.jackhuang.hmcl.download.RemoteVersion; import org.jackhuang.hmcl.download.VersionList; +import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.io.HttpRequest; -import org.jackhuang.hmcl.util.versioning.VersionNumber; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; +import org.jackhuang.hmcl.util.io.NetworkUtils; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import java.util.Collections; -import java.util.Map; import java.util.concurrent.CompletableFuture; /** - * * @author huangyuhui */ public final class LiteLoaderBMCLVersionList extends VersionList { @@ -47,66 +42,44 @@ public final class LiteLoaderBMCLVersionList extends VersionList entry : branch.getLiteLoader().entrySet()) { - String branchName = entry.getKey(); - LiteLoaderVersion v = entry.getValue(); - if ("latest".equals(branchName)) - continue; + private final LiteLoaderVersion build; + private final String version; - String version = v.getVersion(); - String url = "https://bmclapi2.bangbang93.com/liteloader/download?version=" + version; - if (snapshot) { - try { - version = version.replace("SNAPSHOT", getLatestSnapshotVersion(repository.getUrl() + "com/mumfrey/liteloader/" + v.getVersion() + "/")); - url = repository.getUrl() + "com/mumfrey/liteloader/" + v.getVersion() + "/liteloader-" + version + "-release.jar"; - } catch (Exception ignore) { - } - } - - versions.put(key, new LiteLoaderRemoteVersion(gameVersion, - version, Collections.singletonList(url), - v.getTweakClass(), v.getLibraries() - )); + public LiteLoaderBMCLVersion(LiteLoaderVersion build, String version) { + this.build = build; + this.version = version; } } @Override public CompletableFuture refreshAsync() { - return HttpRequest.GET(downloadProvider.injectURL(LITELOADER_LIST)).getJsonAsync(LiteLoaderVersionsRoot.class) - .thenAcceptAsync(root -> { - lock.writeLock().lock(); + throw new UnsupportedOperationException(); + } + @Override + public CompletableFuture refreshAsync(String gameVersion) { + return HttpRequest.GET( + downloadProvider.injectURL("https://bmclapi2.bangbang93.com/liteloader/list"), Pair.pair("mcversion", gameVersion) + ) + .getJsonAsync(LiteLoaderBMCLVersion.class) + .thenAccept(v -> { + lock.writeLock().lock(); try { versions.clear(); - for (Map.Entry entry : root.getVersions().entrySet()) { - String gameVersion = entry.getKey(); - LiteLoaderGameVersions liteLoader = entry.getValue(); - - String gg = VersionNumber.normalize(gameVersion); - doBranch(gg, gameVersion, liteLoader.getRepoitory(), liteLoader.getArtifacts(), false); - doBranch(gg, gameVersion, liteLoader.getRepoitory(), liteLoader.getSnapshots(), true); - } + versions.put(gameVersion, new LiteLoaderRemoteVersion( + gameVersion, v.version, RemoteVersion.Type.UNCATEGORIZED, + Collections.singletonList(NetworkUtils.withQuery( + downloadProvider.injectURL("https://bmclapi2.bangbang93.com/liteloader/download"), + Collections.singletonMap("version", v.version) + )), + v.build.getTweakClass(), v.build.getLibraries() + )); } finally { lock.writeLock().unlock(); } }); } - - public static final String LITELOADER_LIST = "http://dl.liteloader.com/versions/versions.json"; - - private static String getLatestSnapshotVersion(String repo) throws Exception { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(repo + "maven-metadata.xml"); - Element r = doc.getDocumentElement(); - Element snapshot = (Element) r.getElementsByTagName("snapshot").item(0); - Node timestamp = snapshot.getElementsByTagName("timestamp").item(0); - Node buildNumber = snapshot.getElementsByTagName("buildNumber").item(0); - return timestamp.getTextContent() + "-" + buildNumber.getTextContent(); - } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderRemoteVersion.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderRemoteVersion.java index 7bdedc71b..ee7e05009 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderRemoteVersion.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderRemoteVersion.java @@ -30,6 +30,7 @@ import java.util.List; public class LiteLoaderRemoteVersion extends RemoteVersion { private final String tweakClass; private final Collection libraries; + /** * Constructor. * @@ -37,8 +38,8 @@ public class LiteLoaderRemoteVersion extends RemoteVersion { * @param selfVersion the version string of the remote version. * @param urls the installer or universal jar original URL. */ - LiteLoaderRemoteVersion(String gameVersion, String selfVersion, List urls, String tweakClass, Collection libraries) { - super(LibraryAnalyzer.LibraryType.LITELOADER.getPatchId(), gameVersion, selfVersion, null, urls); + LiteLoaderRemoteVersion(String gameVersion, String selfVersion, Type type, List urls, String tweakClass, Collection libraries) { + super(LibraryAnalyzer.LibraryType.LITELOADER.getPatchId(), gameVersion, selfVersion, null, type, urls); this.tweakClass = tweakClass; this.libraries = libraries; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java index 35b7bebd3..3f95c06d5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/liteloader/LiteLoaderVersionList.java @@ -18,21 +18,20 @@ package org.jackhuang.hmcl.download.liteloader; import org.jackhuang.hmcl.download.DownloadProvider; +import org.jackhuang.hmcl.download.RemoteVersion; import org.jackhuang.hmcl.download.VersionList; import org.jackhuang.hmcl.util.io.HttpRequest; -import org.jackhuang.hmcl.util.versioning.VersionNumber; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; +import java.io.IOException; +import java.io.UncheckedIOException; import java.util.Collections; import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; /** - * * @author huangyuhui */ public final class LiteLoaderVersionList extends VersionList { @@ -45,52 +44,39 @@ public final class LiteLoaderVersionList extends VersionList entry : branch.getLiteLoader().entrySet()) { - String branchName = entry.getKey(); - LiteLoaderVersion v = entry.getValue(); - if ("latest".equals(branchName)) - continue; - - String version = v.getVersion(); - String url = repository.getUrl() + "com/mumfrey/liteloader/" + gameVersion + "/" + v.getFile(); - if (snapshot) { - try { - version = version.replace("SNAPSHOT", getLatestSnapshotVersion(repository.getUrl() + "com/mumfrey/liteloader/" + v.getVersion() + "/")); - url = repository.getUrl() + "com/mumfrey/liteloader/" + v.getVersion() + "/liteloader-" + version + "-release.jar"; - } catch (Exception ignore) { - } - } - - versions.put(key, new LiteLoaderRemoteVersion(gameVersion, - version, Collections.singletonList(url), - v.getTweakClass(), v.getLibraries() - )); - } - } + public static final String LITELOADER_LIST = "https://dl.liteloader.com/versions/versions.json"; @Override - public CompletableFuture refreshAsync() { + public CompletableFuture refreshAsync(String gameVersion) { return HttpRequest.GET(downloadProvider.injectURL(LITELOADER_LIST)).getJsonAsync(LiteLoaderVersionsRoot.class) .thenAcceptAsync(root -> { + LiteLoaderGameVersions versions = root.getVersions().get(gameVersion); + if (versions == null) { + return; + } + + LiteLoaderRemoteVersion snapshot = null; + if (versions.getSnapshots() != null) { + try { + snapshot = loadSnapshotVersion(gameVersion, versions.getSnapshots().getLiteLoader().get("latest")); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + lock.writeLock().lock(); - try { - versions.clear(); + this.versions.clear(); - for (Map.Entry entry : root.getVersions().entrySet()) { - String gameVersion = entry.getKey(); - LiteLoaderGameVersions liteLoader = entry.getValue(); + if (versions.getRepoitory() != null && versions.getArtifacts() != null) { + loadArtifactVersion(gameVersion, versions.getRepoitory(), versions.getArtifacts()); + } - String gg = VersionNumber.normalize(gameVersion); - doBranch(gg, gameVersion, liteLoader.getRepoitory(), liteLoader.getArtifacts(), false); - doBranch(gg, gameVersion, liteLoader.getRepoitory(), liteLoader.getSnapshots(), true); + if (snapshot != null) { + this.versions.put(gameVersion, snapshot); } } finally { lock.writeLock().unlock(); @@ -98,16 +84,40 @@ public final class LiteLoaderVersionList extends VersionList refreshAsync() { + throw new UnsupportedOperationException(); + } - private static String getLatestSnapshotVersion(String repo) throws Exception { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(repo + "maven-metadata.xml"); - Element r = doc.getDocumentElement(); - Element snapshot = (Element) r.getElementsByTagName("snapshot").item(0); - Node timestamp = snapshot.getElementsByTagName("timestamp").item(0); - Node buildNumber = snapshot.getElementsByTagName("buildNumber").item(0); - return timestamp.getTextContent() + "-" + buildNumber.getTextContent(); + private void loadArtifactVersion(String gameVersion, LiteLoaderRepository repository, LiteLoaderBranch branch) { + for (Map.Entry entry : branch.getLiteLoader().entrySet()) { + String branchName = entry.getKey(); + LiteLoaderVersion v = entry.getValue(); + if ("latest".equals(branchName)) + continue; + + versions.put(gameVersion, new LiteLoaderRemoteVersion( + gameVersion, v.getVersion(), RemoteVersion.Type.RELEASE, + Collections.singletonList(repository.getUrl() + "com/mumfrey/liteloader/" + gameVersion + "/" + v.getFile()), + v.getTweakClass(), v.getLibraries() + )); + } + } + + // Workaround for https://github.com/HMCL-dev/HMCL/issues/3147: Some LiteLoader artifacts aren't published on http://dl.liteloader.com/repo + private static final String SNAPSHOT_METADATA = "https://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/%s-SNAPSHOT/maven-metadata.xml"; + private static final String SNAPSHOT_FILE = "https://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/%s-SNAPSHOT/liteloader-%s-%s-%s-release.jar"; + + private LiteLoaderRemoteVersion loadSnapshotVersion(String gameVersion, LiteLoaderVersion v) throws IOException { + String root = HttpRequest.GET(String.format(SNAPSHOT_METADATA, gameVersion)).getString(); + Document document = Jsoup.parseBodyFragment(root); + String timestamp = Objects.requireNonNull(document.select("timestamp"), "timestamp").text(); + String buildNumber = Objects.requireNonNull(document.select("buildNumber"), "buildNumber").text(); + + return new LiteLoaderRemoteVersion( + gameVersion, timestamp + "-" + buildNumber, RemoteVersion.Type.SNAPSHOT, + Collections.singletonList(String.format(SNAPSHOT_FILE, gameVersion, gameVersion, timestamp, buildNumber)), + v.getTweakClass(), v.getLibraries() + ); } }