diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java index 5e7c90e6b6..ccda9d7e76 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java @@ -34,8 +34,8 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.StackPane; import org.jackhuang.hmcl.download.cleanroom.CleanroomInstallTask; -import org.jackhuang.hmcl.download.fabric.FabricAPIInstallTask; import org.jackhuang.hmcl.download.fabric.FabricInstallTask; +import org.jackhuang.hmcl.download.fabriclike.ModrinthComponentInstallTask; import org.jackhuang.hmcl.download.forge.ForgeNewInstallTask; import org.jackhuang.hmcl.download.forge.ForgeOldInstallTask; import org.jackhuang.hmcl.download.game.GameAssetDownloadTask; @@ -46,7 +46,6 @@ import org.jackhuang.hmcl.download.neoforge.NeoForgeInstallTask; import org.jackhuang.hmcl.download.neoforge.NeoForgeOldInstallTask; import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask; -import org.jackhuang.hmcl.download.quilt.QuiltAPIInstallTask; import org.jackhuang.hmcl.download.quilt.QuiltInstallTask; import org.jackhuang.hmcl.game.HMCLModpackInstallTask; import org.jackhuang.hmcl.java.JavaInstallTask; @@ -171,7 +170,7 @@ public void onRunning(Task task) { } else if (task instanceof CleanroomInstallTask) { task.setName(i18n("install.installer.install", i18n("install.installer.cleanroom"))); } else if (task instanceof LegacyFabricInstallTask) { - task.setName(i18n("install.installer.install", i18n("install.installer.legacyfabric"))); + task.setName(i18n("install.installer.install", i18n("install.installer.legacy-fabric"))); } else if (task instanceof ForgeNewInstallTask || task instanceof ForgeOldInstallTask) { task.setName(i18n("install.installer.install", i18n("install.installer.forge"))); } else if (task instanceof NeoForgeInstallTask || task instanceof NeoForgeOldInstallTask) { @@ -182,12 +181,10 @@ public void onRunning(Task task) { task.setName(i18n("install.installer.install", i18n("install.installer.optifine"))); } else if (task instanceof FabricInstallTask) { task.setName(i18n("install.installer.install", i18n("install.installer.fabric"))); - } else if (task instanceof FabricAPIInstallTask) { - task.setName(i18n("install.installer.install", i18n("install.installer.fabric-api"))); + } else if (task instanceof ModrinthComponentInstallTask modrinthComponentInstallTask) { + task.setName(i18n("install.installer.install", i18n("install.installer." + modrinthComponentInstallTask.getVersion().projectId()))); } else if (task instanceof QuiltInstallTask) { task.setName(i18n("install.installer.install", i18n("install.installer.quilt"))); - } else if (task instanceof QuiltAPIInstallTask) { - task.setName(i18n("install.installer.install", i18n("install.installer.quilt-api"))); } else if (task instanceof CurseCompletionTask || task instanceof ModrinthCompletionTask || task instanceof ServerModpackCompletionTask || task instanceof McbbsModpackCompletionTask) { task.setName(i18n("modpack.completion")); } else if (task instanceof ModpackInstallTask) { @@ -453,8 +450,8 @@ private StageNode(String stage) { case "hmcl.install.optifine" -> i18n("install.installer.install", i18n("install.installer.optifine") + " " + stageValue); case "hmcl.install.fabric" -> i18n("install.installer.install", i18n("install.installer.fabric") + " " + stageValue); case "hmcl.install.fabric-api" -> i18n("install.installer.install", i18n("install.installer.fabric-api") + " " + stageValue); - case "hmcl.install.legacyfabric" -> i18n("install.installer.install", i18n("install.installer.legacyfabric") + " " + stageValue); - case "hmcl.install.legacyfabric-api" -> i18n("install.installer.install", i18n("install.installer.legacyfabric-api") + " " + stageValue); + case "hmcl.install.legacyfabric" -> i18n("install.installer.install", i18n("install.installer.legacy-fabric") + " " + stageValue); + case "hmcl.install.legacyfabric-api" -> i18n("install.installer.install", i18n("install.installer.legacy-fabric-api") + " " + stageValue); case "hmcl.install.quilt" -> i18n("install.installer.install", i18n("install.installer.quilt") + " " + stageValue); case "hmcl.install.quilt-api" -> i18n("install.installer.install", i18n("install.installer.quilt-api") + " " + stageValue); default -> i18n(stageKey); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java index 8479581475..b5808d3672 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java @@ -30,20 +30,18 @@ import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.*; -import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.download.ComponentRemoteVersion; import org.jackhuang.hmcl.download.ComponentVersionList; +import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.download.cleanroom.CleanroomRemoteVersion; -import org.jackhuang.hmcl.download.fabric.FabricAPIRemoteVersion; import org.jackhuang.hmcl.download.fabric.FabricRemoteVersion; +import org.jackhuang.hmcl.download.fabriclike.ModrinthComponentRemoteVersion; import org.jackhuang.hmcl.download.forge.ForgeRemoteVersion; import org.jackhuang.hmcl.download.game.GameRemoteVersion; -import org.jackhuang.hmcl.download.legacyfabric.LegacyFabricAPIRemoteVersion; import org.jackhuang.hmcl.download.legacyfabric.LegacyFabricRemoteVersion; import org.jackhuang.hmcl.download.liteloader.LiteLoaderRemoteVersion; import org.jackhuang.hmcl.download.neoforge.NeoForgeRemoteVersion; import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion; -import org.jackhuang.hmcl.download.quilt.QuiltAPIRemoteVersion; import org.jackhuang.hmcl.download.quilt.QuiltRemoteVersion; import org.jackhuang.hmcl.game.GameComponentType; import org.jackhuang.hmcl.setting.GameInstanceIconType; @@ -279,12 +277,20 @@ else if (remoteVersion instanceof CleanroomRemoteVersion) iconType = GameInstanceIconType.CLEANROOM; else if (remoteVersion instanceof NeoForgeRemoteVersion) iconType = GameInstanceIconType.NEO_FORGE; - else if (remoteVersion instanceof LegacyFabricRemoteVersion || remoteVersion instanceof LegacyFabricAPIRemoteVersion) + else if (remoteVersion instanceof LegacyFabricRemoteVersion) iconType = GameInstanceIconType.LEGACY_FABRIC; - else if (remoteVersion instanceof FabricRemoteVersion || remoteVersion instanceof FabricAPIRemoteVersion) + else if (remoteVersion instanceof FabricRemoteVersion) iconType = GameInstanceIconType.FABRIC; - else if (remoteVersion instanceof QuiltRemoteVersion || remoteVersion instanceof QuiltAPIRemoteVersion) + else if (remoteVersion instanceof QuiltRemoteVersion) iconType = GameInstanceIconType.QUILT; + else if (remoteVersion instanceof ModrinthComponentRemoteVersion modrinthComponentRemoteVersion) { + iconType = switch (modrinthComponentRemoteVersion.getComponentType()) { + case LEGACY_FABRIC_API -> GameInstanceIconType.LEGACY_FABRIC; + case FABRIC_API -> GameInstanceIconType.FABRIC; + case QUILT_API -> GameInstanceIconType.QUILT; + default -> GameInstanceIconType.COMMAND; + }; + } else iconType = GameInstanceIconType.COMMAND; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadPage.java index 27af95016f..552e799c9d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadPage.java @@ -29,11 +29,13 @@ import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.stage.FileChooser; -import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.game.*; -import org.jackhuang.hmcl.addon.mod.ModLoaderType; import org.jackhuang.hmcl.addon.RemoteAddon; import org.jackhuang.hmcl.addon.RemoteAddonRepository; +import org.jackhuang.hmcl.addon.mod.ModLoaderType; +import org.jackhuang.hmcl.download.DownloadProvider; +import org.jackhuang.hmcl.game.GameInstanceID; +import org.jackhuang.hmcl.game.HMCLGameInstance; +import org.jackhuang.hmcl.game.HMCLGameRepository; import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; @@ -481,7 +483,7 @@ private static final class AddonItem extends StackPane { content.addTag(i18n("install.installer.quilt")); break; case LEGACY_FABRIC: - content.addTag(i18n("install.installer.legacyfabric")); + content.addTag(i18n("install.installer.legacy-fabric")); break; } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/ModListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/ModListPage.java index 02d69ed8f0..45124800b2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/ModListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/ModListPage.java @@ -43,12 +43,12 @@ import javafx.util.Duration; import org.jackhuang.hmcl.addon.RemoteAddon; import org.jackhuang.hmcl.addon.RemoteAddonRepository; -import org.jackhuang.hmcl.addon.repository.CurseForgeRemoteAddonRepository; -import org.jackhuang.hmcl.addon.repository.ModrinthRemoteAddonRepository; -import org.jackhuang.hmcl.game.*; import org.jackhuang.hmcl.addon.mod.LocalModFile; import org.jackhuang.hmcl.addon.mod.ModLoaderType; import org.jackhuang.hmcl.addon.mod.ModManager; +import org.jackhuang.hmcl.addon.repository.CurseForgeRemoteAddonRepository; +import org.jackhuang.hmcl.addon.repository.ModrinthRemoteAddonRepository; +import org.jackhuang.hmcl.game.*; import org.jackhuang.hmcl.setting.DownloadProviders; import org.jackhuang.hmcl.setting.GameDirectory; import org.jackhuang.hmcl.setting.GameInstanceIconType; @@ -75,7 +75,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.*; -import java.util.Objects; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.ReentrantLock; @@ -739,7 +738,7 @@ private static final class ModInfoDialog extends JFXDialogLayout { String loaderName = switch (modLoaderType) { case FORGE -> i18n("install.installer.forge"); case CLEANROOM -> i18n("install.installer.cleanroom"); - case LEGACY_FABRIC -> i18n("install.installer.legacyfabric"); + case LEGACY_FABRIC -> i18n("install.installer.legacy-fabric"); case NEO_FORGE -> i18n("install.installer.neoforge"); case FABRIC -> i18n("install.installer.fabric"); case LITE_LOADER -> i18n("install.installer.liteloader"); @@ -894,7 +893,7 @@ protected void updateControl(ModInfoObject dataItem, boolean empty) { warning.add(i18n("mods.warning.loader_mismatch")); switch (dataItem.getModInfo().getModLoaderType()) { case FORGE -> content.addTagWarning(i18n("install.installer.forge")); - case LEGACY_FABRIC -> content.addTagWarning(i18n("install.installer.legacyfabric")); + case LEGACY_FABRIC -> content.addTagWarning(i18n("install.installer.legacy-fabric")); case CLEANROOM -> content.addTagWarning(i18n("install.installer.cleanroom")); case NEO_FORGE -> content.addTagWarning(i18n("install.installer.neoforge")); case FABRIC -> content.addTagWarning(i18n("install.installer.fabric")); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 672b254bb3..7dd88bb41c 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -765,7 +765,7 @@ install.installer.do_not_install=Do not install install.installer.fabric=Fabric install.installer.fabric-api=Fabric API install.installer.legacyfabric=Legacy Fabric -install.installer.legacyfabric-api=Legacy Fabric API +install.installer.legacy-fabric-api=Legacy Fabric API install.installer.fabric-quilt-api.warning=%1$s is a mod and will be installed into the mod directory of the game instance. Please do not change the working directory of the game, or the %1$s will not function. If you do want to change the directory, you should reinstall it. install.installer.forge=Forge install.installer.neoforge=NeoForge diff --git a/HMCL/src/main/resources/assets/lang/I18N_ar.properties b/HMCL/src/main/resources/assets/lang/I18N_ar.properties index 3b1e9c7f9a..23250b2d61 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ar.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ar.properties @@ -721,7 +721,7 @@ install.installer.do_not_install=لا تثبّت install.installer.fabric=Fabric install.installer.fabric-api=Fabric API install.installer.legacyfabric=Legacy Fabric -install.installer.legacyfabric-api=Legacy Fabric API +install.installer.legacy-fabric-api=Legacy Fabric API install.installer.fabric-quilt-api.warning=%1$s هو مود وسيتم تثبيته في مجلد مودات نسخة اللعبة. يُرجى عدم تغيير مجلد عمل اللعبة، وإلا لن يعمل %1$s. إذا أردت تغيير المجلد، يجب إعادة تثبيته. install.installer.forge=Forge install.installer.neoforge=NeoForge diff --git a/HMCL/src/main/resources/assets/lang/I18N_de.properties b/HMCL/src/main/resources/assets/lang/I18N_de.properties index 059c0fe977..2bd26eec54 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_de.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_de.properties @@ -762,7 +762,7 @@ install.installer.do_not_install=Nicht installieren install.installer.fabric=Fabric install.installer.fabric-api=Fabric API install.installer.legacyfabric=Legacy Fabric -install.installer.legacyfabric-api=Legacy Fabric API +install.installer.legacy-fabric-api=Legacy Fabric API install.installer.fabric-quilt-api.warning=%1$s ist ein Mod und wird in das Mod-Verzeichnis der Spielinstanz installiert. Bitte ändern Sie das Arbeitsverzeichnis des Spiels nicht, da der %1$s sonst nicht funktioniert. Wenn Sie das Verzeichnis ändern möchten, sollten Sie es neu installieren. install.installer.forge=Forge install.installer.neoforge=NeoForge diff --git a/HMCL/src/main/resources/assets/lang/I18N_uk.properties b/HMCL/src/main/resources/assets/lang/I18N_uk.properties index 25044542c8..2589d284ca 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_uk.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_uk.properties @@ -722,7 +722,7 @@ install.installer.fabric=Fabric install.installer.fabric-api=Fabric API install.installer.fabric-quilt-api.warning=%1$s - це мод, і він буде встановлений у каталог модів екземпляра гри. Не змінюйте робочий каталог гри, інакше %1$s не працюватиме. Якщо ви все ж хочете змінити каталог, вам слід перевстановити його. install.installer.legacyfabric=Legacy Fabric -install.installer.legacyfabric-api=Legacy Fabric API +install.installer.legacy-fabric-api=Legacy Fabric API install.installer.forge=Forge install.installer.neoforge=NeoForge install.installer.game=Minecraft diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 48e4524a3d..b8f642d64b 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -577,7 +577,7 @@ install.installer.do_not_install=不安裝 install.installer.fabric=Fabric install.installer.fabric-api=Fabric API install.installer.legacyfabric=Legacy Fabric -install.installer.legacyfabric-api=Legacy Fabric API +install.installer.legacy-fabric-api=Legacy Fabric API install.installer.fabric-quilt-api.warning=%1$s 是一個模組,將會被安裝到新遊戲的模組目錄。請你在安裝遊戲後不要修改目前遊戲的「執行路徑」設定。如果你在之後修改了相關設定,則需要重新安裝 %1$s。 install.installer.forge=Forge install.installer.neoforge=NeoForge diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index cc1c47a2dc..cb09a9e0c2 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -582,7 +582,7 @@ install.installer.cleanroom=Cleanroom install.installer.do_not_install=不安装 install.installer.fabric=Fabric install.installer.legacyfabric=Legacy Fabric -install.installer.legacyfabric-api=Legacy Fabric API +install.installer.legacy-fabric-api=Legacy Fabric API install.installer.fabric-api=Fabric API install.installer.fabric-quilt-api.warning=%1$s 是一个模组,将会被安装到新游戏的模组文件夹。请你在安装游戏后不要修改当前游戏的“版本隔离”设置。如果你在之后修改了相关设置,则需要重新安装 %1$s。 install.installer.forge=Forge 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 b301f6f196..e1b455c50f 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java @@ -18,16 +18,14 @@ package org.jackhuang.hmcl.download; import org.jackhuang.hmcl.download.cleanroom.CleanroomVersionList; -import org.jackhuang.hmcl.download.fabric.FabricAPIVersionList; import org.jackhuang.hmcl.download.fabric.FabricVersionList; +import org.jackhuang.hmcl.download.fabriclike.ModrinthComponentVersionList; import org.jackhuang.hmcl.download.forge.ForgeBMCLVersionList; import org.jackhuang.hmcl.download.game.GameVersionList; -import org.jackhuang.hmcl.download.legacyfabric.LegacyFabricAPIVersionList; import org.jackhuang.hmcl.download.legacyfabric.LegacyFabricVersionList; import org.jackhuang.hmcl.download.liteloader.LiteLoaderBMCLVersionList; import org.jackhuang.hmcl.download.neoforge.NeoForgeBMCLVersionList; import org.jackhuang.hmcl.download.optifine.OptiFineBMCLVersionList; -import org.jackhuang.hmcl.download.quilt.QuiltAPIVersionList; import org.jackhuang.hmcl.download.quilt.QuiltVersionList; import org.jackhuang.hmcl.game.GameComponentType; import org.jackhuang.hmcl.util.Pair; @@ -46,16 +44,16 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider { private final String apiRoot; private final GameVersionList game; private final FabricVersionList fabric; - private final FabricAPIVersionList fabricApi; + private final ModrinthComponentVersionList fabricApi; private final ForgeBMCLVersionList forge; private final CleanroomVersionList cleanroom; private final LegacyFabricVersionList legacyFabric; - private final LegacyFabricAPIVersionList legacyFabricApi; + private final ModrinthComponentVersionList legacyFabricApi; private final NeoForgeBMCLVersionList neoforge; private final LiteLoaderBMCLVersionList liteLoader; private final OptiFineBMCLVersionList optifine; private final QuiltVersionList quilt; - private final QuiltAPIVersionList quiltApi; + private final ModrinthComponentVersionList quiltApi; private final List> replacement; private final List> fallbackReplacement; @@ -63,16 +61,16 @@ public BMCLAPIDownloadProvider(String apiRoot) { this.apiRoot = apiRoot; this.game = new GameVersionList(this); this.fabric = new FabricVersionList(this); - this.fabricApi = new FabricAPIVersionList(this); + this.fabricApi = new ModrinthComponentVersionList(this, GameComponentType.FABRIC_API, "P7dR8mSH"); this.forge = new ForgeBMCLVersionList(apiRoot); this.cleanroom = new CleanroomVersionList(this); this.neoforge = new NeoForgeBMCLVersionList(apiRoot); this.liteLoader = new LiteLoaderBMCLVersionList(this); this.optifine = new OptiFineBMCLVersionList(apiRoot); this.quilt = new QuiltVersionList(this); - this.quiltApi = new QuiltAPIVersionList(this); + this.quiltApi = new ModrinthComponentVersionList(this, GameComponentType.QUILT_API, "qvIfYCYJ"); this.legacyFabric = new LegacyFabricVersionList(this); - this.legacyFabricApi = new LegacyFabricAPIVersionList(this); + this.legacyFabricApi = new ModrinthComponentVersionList(this, GameComponentType.LEGACY_FABRIC_API, "9CJED7xi"); this.replacement = List.of( pair("https://bmclapi2.bangbang93.com", apiRoot), diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MojangDownloadProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MojangDownloadProvider.java index 5e2ec3cac9..0b5d7df6cc 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MojangDownloadProvider.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MojangDownloadProvider.java @@ -18,16 +18,14 @@ package org.jackhuang.hmcl.download; import org.jackhuang.hmcl.download.cleanroom.CleanroomVersionList; -import org.jackhuang.hmcl.download.fabric.FabricAPIVersionList; import org.jackhuang.hmcl.download.fabric.FabricVersionList; +import org.jackhuang.hmcl.download.fabriclike.ModrinthComponentVersionList; import org.jackhuang.hmcl.download.forge.ForgeVersionList; import org.jackhuang.hmcl.download.game.GameVersionList; -import org.jackhuang.hmcl.download.legacyfabric.LegacyFabricAPIVersionList; import org.jackhuang.hmcl.download.legacyfabric.LegacyFabricVersionList; import org.jackhuang.hmcl.download.liteloader.LiteLoaderVersionList; import org.jackhuang.hmcl.download.neoforge.NeoForgeOfficialVersionList; import org.jackhuang.hmcl.download.optifine.OptiFineBMCLVersionList; -import org.jackhuang.hmcl.download.quilt.QuiltAPIVersionList; import org.jackhuang.hmcl.download.quilt.QuiltVersionList; import org.jackhuang.hmcl.game.GameComponentType; import org.jackhuang.hmcl.util.io.NetworkUtils; @@ -42,16 +40,16 @@ public class MojangDownloadProvider implements DownloadProvider { private final GameVersionList game; private final FabricVersionList fabric; - private final FabricAPIVersionList fabricApi; + private final ModrinthComponentVersionList fabricApi; private final ForgeVersionList forge; private final NeoForgeOfficialVersionList neoforge; private final CleanroomVersionList cleanroom; private final LiteLoaderVersionList liteLoader; private final OptiFineBMCLVersionList optifine; private final QuiltVersionList quilt; - private final QuiltAPIVersionList quiltApi; + private final ModrinthComponentVersionList quiltApi; private final LegacyFabricVersionList legacyFabric; - private final LegacyFabricAPIVersionList legacyFabricApi; + private final ModrinthComponentVersionList legacyFabricApi; public MojangDownloadProvider() { // If there is no official download channel available, fallback to BMCLAPI. @@ -59,16 +57,16 @@ public MojangDownloadProvider() { this.game = new GameVersionList(this); this.fabric = new FabricVersionList(this); - this.fabricApi = new FabricAPIVersionList(this); + this.fabricApi = new ModrinthComponentVersionList(this, GameComponentType.FABRIC_API, "P7dR8mSH"); this.forge = new ForgeVersionList(this); this.neoforge = new NeoForgeOfficialVersionList(this); this.cleanroom = new CleanroomVersionList(this); this.liteLoader = new LiteLoaderVersionList(this); this.optifine = new OptiFineBMCLVersionList(apiRoot); this.quilt = new QuiltVersionList(this); - this.quiltApi = new QuiltAPIVersionList(this); + this.quiltApi = new ModrinthComponentVersionList(this, GameComponentType.QUILT_API, "qvIfYCYJ"); this.legacyFabric = new LegacyFabricVersionList(this); - this.legacyFabricApi = new LegacyFabricAPIVersionList(this); + this.legacyFabricApi = new ModrinthComponentVersionList(this, GameComponentType.LEGACY_FABRIC_API, "9CJED7xi"); } @Override diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIRemoteVersion.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIRemoteVersion.java deleted file mode 100644 index 2d923f0130..0000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIRemoteVersion.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2021 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.download.fabric; - -import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.download.ComponentRemoteVersion; -import org.jackhuang.hmcl.game.GameComponentType; -import org.jackhuang.hmcl.game.GameInstanceManifest; -import org.jackhuang.hmcl.game.GameInstancePatch; -import org.jackhuang.hmcl.addon.RemoteAddon; -import org.jackhuang.hmcl.task.Task; - -import java.nio.file.Path; -import java.time.Instant; -import java.util.List; - -public class FabricAPIRemoteVersion extends ComponentRemoteVersion { - private final String fullVersion; - private final RemoteAddon.Version version; - - /** - * Constructor. - * - * @param gameVersion the Minecraft version that this remote version suits. - * @param selfVersion the version string of the remote version. - * @param urls the installer or universal jar original URL. - */ - FabricAPIRemoteVersion(String gameVersion, String selfVersion, String fullVersion, Instant datePublished, RemoteAddon.Version version, List urls) { - super(GameComponentType.FABRIC_API, gameVersion, selfVersion, datePublished, urls); - - this.fullVersion = fullVersion; - this.version = version; - } - - @Override - public String getFullVersion() { - return fullVersion; - } - - public RemoteAddon.Version getVersion() { - return version; - } - - @Override - public Task getInstallTask( - DefaultDependencyManager dependencyManager, - GameInstanceManifest baseManifest, - Path modsDirectory) { - return new FabricAPIInstallTask(dependencyManager, baseManifest, this, modsDirectory); - } - - @Override - public int compareTo(ComponentRemoteVersion o) { - if (!(o instanceof FabricAPIRemoteVersion)) return 0; - return -this.getReleaseDate().compareTo(o.getReleaseDate()); - } -} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIVersionList.java deleted file mode 100644 index 83fc136114..0000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIVersionList.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2021 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.download.fabric; - -import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.download.ComponentVersionList; -import org.jackhuang.hmcl.addon.RemoteAddon; -import org.jackhuang.hmcl.addon.repository.ModrinthRemoteAddonRepository; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.Lang; - -import java.util.Collections; - -public class FabricAPIVersionList extends ComponentVersionList { - - private final DownloadProvider downloadProvider; - - public FabricAPIVersionList(DownloadProvider downloadProvider) { - this.downloadProvider = downloadProvider; - } - - @Override - public boolean hasType() { - return false; - } - - @Override - public Task refreshAsync() { - return Task.runAsync(() -> { - for (RemoteAddon.Version modVersion : Lang.toIterable(ModrinthRemoteAddonRepository.MODS.getRemoteVersionsById(downloadProvider, "P7dR8mSH"))) { - for (String gameVersion : modVersion.gameVersions()) { - versions.put(gameVersion, new FabricAPIRemoteVersion(gameVersion, modVersion.version(), modVersion.name(), modVersion.datePublished(), modVersion, - Collections.singletonList(modVersion.file().url()))); - } - } - }); - } -} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricInstallTask.java index 6a89cab808..c4ad60f560 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricInstallTask.java @@ -19,6 +19,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import org.jackhuang.hmcl.download.ComponentRemoteVersion; import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.download.UnsupportedInstallationException; import org.jackhuang.hmcl.download.game.GameLibrariesTask; @@ -38,15 +39,15 @@ * * @author huangyuhui */ -public final class FabricInstallTask extends Task { +public class FabricInstallTask extends Task { private final DefaultDependencyManager dependencyManager; private final GameInstanceManifest manifest; - private final FabricRemoteVersion remote; + private final ComponentRemoteVersion remote; private final GetTask launchMetaTask; private final List> dependencies = new ArrayList<>(1); - public FabricInstallTask(DefaultDependencyManager dependencyManager, GameInstanceManifest manifest, FabricRemoteVersion remoteVersion) { + public FabricInstallTask(DefaultDependencyManager dependencyManager, GameInstanceManifest manifest, ComponentRemoteVersion remoteVersion) { if (!manifest.isModifiable()) { throw new IllegalArgumentException("Manifest is not modifiable"); } @@ -88,15 +89,14 @@ public boolean isRelyingOnDependencies() { @Override public void execute() throws IOException { FabricInfo fabricInfo = JsonUtils.GSON.fromJson(launchMetaTask.getResult(), FabricInfo.class); - if (fabricInfo == null) - throw new IOException("Fabric metadata is invalid"); + if (fabricInfo == null) throw new IOException("Fabric metadata is invalid"); setResult(getPatch(fabricInfo, remote.getGameVersion(), remote.getSelfVersion())); dependencies.add(new GameLibrariesTask(dependencyManager, manifest, true, getResult().getLibraries())); } - private GameInstancePatch getPatch(FabricInfo fabricInfo, String gameVersion, String loaderVersion) { + protected GameInstancePatch getPatch(FabricInfo fabricInfo, String gameVersion, String loaderVersion) { JsonObject launcherMeta = fabricInfo.launcherMeta; Arguments arguments = new Arguments(); @@ -123,96 +123,25 @@ private GameInstancePatch getPatch(FabricInfo fabricInfo, String gameVersion, St } } - libraries.add(new Library(Artifact.fromDescriptor(fabricInfo.intermediary.maven), "https://maven.fabricmc.net/", null)); - libraries.add(new Library(Artifact.fromDescriptor(fabricInfo.loader.maven), "https://maven.fabricmc.net/", null)); + libraries.add(new Library(Artifact.fromDescriptor(fabricInfo.intermediary.maven), getMavenRepositoryByGroup(fabricInfo.intermediary.maven), null)); + libraries.add(new Library(Artifact.fromDescriptor(fabricInfo.loader.maven), getMavenRepositoryByGroup(fabricInfo.loader.maven), null)); return new GameInstancePatch(GameComponentType.FABRIC.getPatchId(), loaderVersion, GameInstancePatch.PRIORITY_LOADER, arguments, mainClass, libraries); } - @JsonSerializable - public static class FabricInfo { - private final LoaderInfo loader; - private final IntermediaryInfo intermediary; - private final JsonObject launcherMeta; - - public FabricInfo(LoaderInfo loader, IntermediaryInfo intermediary, JsonObject launcherMeta) { - this.loader = loader; - this.intermediary = intermediary; - this.launcherMeta = launcherMeta; - } - - public LoaderInfo getLoader() { - return loader; - } - - public IntermediaryInfo getIntermediary() { - return intermediary; - } - - public JsonObject getLauncherMeta() { - return launcherMeta; - } + protected String getMavenRepositoryByGroup(String maven) { + return "https://maven.fabricmc.net/"; } @JsonSerializable - public static class LoaderInfo { - private final String separator; - private final int build; - private final String maven; - private final String version; - private final boolean stable; - - public LoaderInfo(String separator, int build, String maven, String version, boolean stable) { - this.separator = separator; - this.build = build; - this.maven = maven; - this.version = version; - this.stable = stable; - } - - public String getSeparator() { - return separator; - } - - public int getBuild() { - return build; - } - - public String getMaven() { - return maven; - } - - public String getVersion() { - return version; - } - - public boolean isStable() { - return stable; - } + public record FabricInfo(LoaderInfo loader, IntermediaryInfo intermediary, JsonObject launcherMeta) { } @JsonSerializable - public static class IntermediaryInfo { - private final String maven; - private final String version; - private final boolean stable; - - public IntermediaryInfo(String maven, String version, boolean stable) { - this.maven = maven; - this.version = version; - this.stable = stable; - } - - public String getMaven() { - return maven; - } - - public String getVersion() { - return version; - } + public record LoaderInfo(String separator, int build, String maven, String version, boolean stable) { + } - public boolean isStable() { - return stable; - } + @JsonSerializable + public record IntermediaryInfo(String maven, String version, boolean stable) { } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java index 9a3c771430..dae27c75ff 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java @@ -1,6 +1,6 @@ /* * Hello Minecraft! Launcher - * Copyright (C) 2021 huangyuhui and contributors + * Copyright (C) 2026 huangyuhui and contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,64 +18,32 @@ package org.jackhuang.hmcl.download.fabric; import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.download.ComponentVersionList; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.gson.JsonSerializable; -import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.NetworkUtils; +import org.jackhuang.hmcl.download.fabriclike.FabricLikeVersionList; -import java.io.IOException; -import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; - -import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf; - -public final class FabricVersionList extends ComponentVersionList { - private final DownloadProvider downloadProvider; +public final class FabricVersionList extends FabricLikeVersionList { public FabricVersionList(DownloadProvider downloadProvider) { - this.downloadProvider = downloadProvider; + super(downloadProvider); } @Override - public boolean hasType() { - return false; + protected String getLoaderMetaURL() { + return "https://meta.fabricmc.net/v2/versions/loader"; } @Override - public Task refreshAsync() { - return Task.runAsync(() -> { - List gameVersions = getGameVersions(GAME_META_URL); - List loaderVersions = getGameVersions(LOADER_META_URL); - - lock.writeLock().lock(); - - try { - for (String gameVersion : gameVersions) - for (String loaderVersion : loaderVersions) - versions.put(gameVersion, new FabricRemoteVersion(gameVersion, loaderVersion, - Collections.singletonList(getLaunchMetaUrl(gameVersion, loaderVersion)))); - } finally { - lock.writeLock().unlock(); - } - }); + protected String getGameMetaURL() { + return "https://meta.fabricmc.net/v2/versions/game"; } - private static final String LOADER_META_URL = "https://meta.fabricmc.net/v2/versions/loader"; - private static final String GAME_META_URL = "https://meta.fabricmc.net/v2/versions/game"; - - private List getGameVersions(String metaUrl) throws IOException { - String json = NetworkUtils.doGet(downloadProvider.injectURLWithCandidates(metaUrl)); - return JsonUtils.GSON.fromJson(json, listTypeOf(GameVersion.class)) - .stream().map(GameVersion::version).collect(Collectors.toList()); - } - - private static String getLaunchMetaUrl(String gameVersion, String loaderVersion) { + @Override + protected String getLaunchMetaUrl(String gameVersion, String loaderVersion) { return String.format("https://meta.fabricmc.net/v2/versions/loader/%s/%s", gameVersion, loaderVersion); } - @JsonSerializable - private record GameVersion(String version, String maven, boolean stable) { + @Override + protected FabricRemoteVersion createRemoteVersion(String gameVersion, String loaderVersion, List urls) { + return new FabricRemoteVersion(gameVersion, loaderVersion, urls); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/FabricLikeVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/FabricLikeVersionList.java new file mode 100644 index 0000000000..fb6613ecc9 --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/FabricLikeVersionList.java @@ -0,0 +1,89 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2026 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.download.fabriclike; + +import org.jackhuang.hmcl.download.ComponentRemoteVersion; +import org.jackhuang.hmcl.download.ComponentVersionList; +import org.jackhuang.hmcl.download.DownloadProvider; +import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.util.gson.JsonSerializable; +import org.jackhuang.hmcl.util.gson.JsonUtils; +import org.jackhuang.hmcl.util.io.NetworkUtils; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf; + +public abstract class FabricLikeVersionList extends ComponentVersionList { + private final DownloadProvider downloadProvider; + + public FabricLikeVersionList(DownloadProvider downloadProvider) { + this.downloadProvider = downloadProvider; + } + + @Override + public boolean hasType() { + return false; + } + + @Override + public Task refreshAsync() { + return Task.runAsync(() -> { + List gameVersions = getGameVersions(getGameMetaURL()); + List loaderVersions = getGameVersions(getLoaderMetaURL()); + + lock.writeLock().lock(); + + try { + for (String gameVersion : gameVersions) + for (String loaderVersion : loaderVersions) { + gameVersion = normalizeVersion(gameVersion); + versions.put(gameVersion, createRemoteVersion(gameVersion, loaderVersion, + Collections.singletonList(getLaunchMetaUrl(gameVersion, loaderVersion)))); + } + } finally { + lock.writeLock().unlock(); + } + }); + } + + private List getGameVersions(String metaUrl) throws IOException { + String json = NetworkUtils.doGet(downloadProvider.injectURLWithCandidates(metaUrl)); + return JsonUtils.GSON.fromJson(json, listTypeOf(GameVersion.class)) + .stream().map(GameVersion::version).collect(Collectors.toList()); + } + + protected abstract String getLoaderMetaURL(); + + protected abstract String getGameMetaURL(); + + protected abstract String getLaunchMetaUrl(String gameVersion, String loaderVersion); + + protected abstract T createRemoteVersion(String gameVersion, String loaderVersion, List urls); + + protected String normalizeVersion(String version) { + return version; + } + + @JsonSerializable + private record GameVersion(String version, String maven, boolean stable) { + } +} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentInstallTask.java similarity index 63% rename from HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIInstallTask.java rename to HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentInstallTask.java index 03193f9870..9c2564a1c0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricAPIInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentInstallTask.java @@ -1,6 +1,6 @@ /* * Hello Minecraft! Launcher - * Copyright (C) 2021 huangyuhui and contributors + * Copyright (C) 2026 huangyuhui and contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,10 +15,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.jackhuang.hmcl.download.fabric; +package org.jackhuang.hmcl.download.fabriclike; -import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.game.GameInstanceManifest; +import org.jackhuang.hmcl.addon.RemoteAddon; import org.jackhuang.hmcl.game.GameInstancePatch; import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.Task; @@ -29,30 +28,16 @@ import java.util.Collection; import java.util.List; -/** - * Note: Fabric should be installed first. - * - * @author huangyuhui - */ -public final class FabricAPIInstallTask extends Task { - - private final DefaultDependencyManager dependencyManager; - private final GameInstanceManifest manifest; - private final FabricAPIRemoteVersion remote; +public class ModrinthComponentInstallTask extends Task { + private final ModrinthComponentRemoteVersion remote; private final Path modsDirectory; private final List> dependencies = new ArrayList<>(1); - /// @param dependencyManager the dependency manager - /// @param manifest the manifest being installed into /// @param remoteVersion the Fabric API remote version /// @param modsDirectory the target mods directory (must already be resolved by the caller) - public FabricAPIInstallTask( - DefaultDependencyManager dependencyManager, - GameInstanceManifest manifest, - FabricAPIRemoteVersion remoteVersion, + public ModrinthComponentInstallTask( + ModrinthComponentRemoteVersion remoteVersion, Path modsDirectory) { - this.dependencyManager = dependencyManager; - this.manifest = manifest; this.remote = remoteVersion; this.modsDirectory = modsDirectory; } @@ -71,8 +56,12 @@ public boolean isRelyingOnDependencies() { public void execute() throws IOException { dependencies.add(new FileDownloadTask( remote.getVersion().file().url(), - modsDirectory.resolve("fabric-api-" + remote.getVersion().version() + ".jar"), + modsDirectory.resolve(remote.getVersion().file().filename()), remote.getVersion().file().getIntegrityCheck()) ); } + + public RemoteAddon.Version getVersion() { + return remote.getVersion(); + } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIRemoteVersion.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentRemoteVersion.java similarity index 77% rename from HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIRemoteVersion.java rename to HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentRemoteVersion.java index cf238420c5..c55f309dd4 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIRemoteVersion.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentRemoteVersion.java @@ -1,6 +1,6 @@ /* * Hello Minecraft! Launcher - * Copyright (C) 2022 huangyuhui and contributors + * Copyright (C) 2026 huangyuhui and contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,21 +15,21 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.jackhuang.hmcl.download.quilt; +package org.jackhuang.hmcl.download.fabriclike; -import org.jackhuang.hmcl.download.DefaultDependencyManager; +import org.jackhuang.hmcl.addon.RemoteAddon; import org.jackhuang.hmcl.download.ComponentRemoteVersion; +import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.game.GameComponentType; import org.jackhuang.hmcl.game.GameInstanceManifest; import org.jackhuang.hmcl.game.GameInstancePatch; -import org.jackhuang.hmcl.addon.RemoteAddon; import org.jackhuang.hmcl.task.Task; import java.nio.file.Path; import java.time.Instant; import java.util.List; -public class QuiltAPIRemoteVersion extends ComponentRemoteVersion { +public class ModrinthComponentRemoteVersion extends ComponentRemoteVersion { private final String fullVersion; private final RemoteAddon.Version version; @@ -40,8 +40,8 @@ public class QuiltAPIRemoteVersion extends ComponentRemoteVersion { * @param selfVersion the version string of the remote version. * @param urls the installer or universal jar original URL. */ - QuiltAPIRemoteVersion(String gameVersion, String selfVersion, String fullVersion, Instant datePublished, RemoteAddon.Version version, List urls) { - super(GameComponentType.QUILT_API, gameVersion, selfVersion, datePublished, urls); + ModrinthComponentRemoteVersion(GameComponentType type, String gameVersion, String selfVersion, String fullVersion, Instant datePublished, RemoteAddon.Version version, List urls) { + super(type, gameVersion, selfVersion, datePublished, urls); this.fullVersion = fullVersion; this.version = version; @@ -61,12 +61,12 @@ public Task getInstallTask( DefaultDependencyManager dependencyManager, GameInstanceManifest baseManifest, Path modsDirectory) { - return new QuiltAPIInstallTask(dependencyManager, baseManifest, this, modsDirectory); + return new ModrinthComponentInstallTask(this, modsDirectory); } @Override public int compareTo(ComponentRemoteVersion o) { - if (!(o instanceof QuiltAPIRemoteVersion)) return 0; + if (!(o instanceof ModrinthComponentRemoteVersion)) return 0; return -this.getReleaseDate().compareTo(o.getReleaseDate()); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentVersionList.java similarity index 66% rename from HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIVersionList.java rename to HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentVersionList.java index e521735938..73551caae7 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabriclike/ModrinthComponentVersionList.java @@ -1,6 +1,6 @@ /* * Hello Minecraft! Launcher - * Copyright (C) 2022 huangyuhui and contributors + * Copyright (C) 2026 huangyuhui and contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,23 +15,28 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.jackhuang.hmcl.download.quilt; +package org.jackhuang.hmcl.download.fabriclike; -import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.download.ComponentVersionList; import org.jackhuang.hmcl.addon.RemoteAddon; import org.jackhuang.hmcl.addon.repository.ModrinthRemoteAddonRepository; +import org.jackhuang.hmcl.download.ComponentVersionList; +import org.jackhuang.hmcl.download.DownloadProvider; +import org.jackhuang.hmcl.game.GameComponentType; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.Lang; import java.util.Collections; -public class QuiltAPIVersionList extends ComponentVersionList { +public class ModrinthComponentVersionList extends ComponentVersionList { private final DownloadProvider downloadProvider; + private final GameComponentType type; + private final String mrId; - public QuiltAPIVersionList(DownloadProvider downloadProvider) { + public ModrinthComponentVersionList(DownloadProvider downloadProvider, GameComponentType type,String mrId) { this.downloadProvider = downloadProvider; + this.type = type; + this.mrId = mrId; } @Override @@ -42,10 +47,9 @@ public boolean hasType() { @Override public Task refreshAsync() { return Task.runAsync(() -> { - for (RemoteAddon.Version modVersion : Lang.toIterable(ModrinthRemoteAddonRepository.MODS.getRemoteVersionsById(downloadProvider, "qsl"))) { + for (RemoteAddon.Version modVersion : Lang.toIterable(ModrinthRemoteAddonRepository.MODS.getRemoteVersionsById(downloadProvider, mrId))) { for (String gameVersion : modVersion.gameVersions()) { - versions.put(gameVersion, new QuiltAPIRemoteVersion(gameVersion, modVersion.version(), modVersion.name(), modVersion.datePublished(), modVersion, - Collections.singletonList(modVersion.file().url()))); + versions.put(gameVersion, new ModrinthComponentRemoteVersion(type, gameVersion, modVersion.version(), modVersion.name(), modVersion.datePublished(), modVersion, Collections.singletonList(modVersion.file().url()))); } } }); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIInstallTask.java deleted file mode 100644 index 07818feee9..0000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIInstallTask.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2021 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.download.legacyfabric; - -import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.game.GameInstanceManifest; -import org.jackhuang.hmcl.game.GameInstancePatch; -import org.jackhuang.hmcl.task.FileDownloadTask; -import org.jackhuang.hmcl.task.Task; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public final class LegacyFabricAPIInstallTask extends Task { - - private final DefaultDependencyManager dependencyManager; - private final GameInstanceManifest manifest; - private final LegacyFabricAPIRemoteVersion remote; - private final Path modsDirectory; - private final List> dependencies = new ArrayList<>(1); - - /// @param dependencyManager the dependency manager - /// @param manifest the manifest being installed into - /// @param remoteVersion the Legacy Fabric API remote version - /// @param modsDirectory the target mods directory (must already be resolved by the caller) - public LegacyFabricAPIInstallTask( - DefaultDependencyManager dependencyManager, - GameInstanceManifest manifest, - LegacyFabricAPIRemoteVersion remoteVersion, - Path modsDirectory) { - this.dependencyManager = dependencyManager; - this.manifest = manifest; - this.remote = remoteVersion; - this.modsDirectory = modsDirectory; - } - - @Override - public Collection> getDependencies() { - return dependencies; - } - - @Override - public boolean isRelyingOnDependencies() { - return false; - } - - @Override - public void execute() throws IOException { - dependencies.add(new FileDownloadTask( - remote.getVersion().file().url(), - modsDirectory.resolve("legacy-fabric-api-" + remote.getVersion().version() + ".jar"), - remote.getVersion().file().getIntegrityCheck()) - ); - } -} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIRemoteVersion.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIRemoteVersion.java deleted file mode 100644 index 3d11662447..0000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIRemoteVersion.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2022 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.download.legacyfabric; - -import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.download.ComponentRemoteVersion; -import org.jackhuang.hmcl.game.GameComponentType; -import org.jackhuang.hmcl.game.GameInstanceManifest; -import org.jackhuang.hmcl.game.GameInstancePatch; -import org.jackhuang.hmcl.addon.RemoteAddon; -import org.jackhuang.hmcl.task.Task; - -import java.nio.file.Path; -import java.time.Instant; -import java.util.List; - -public class LegacyFabricAPIRemoteVersion extends ComponentRemoteVersion { - private final String fullVersion; - private final RemoteAddon.Version version; - - /** - * Constructor. - * - * @param gameVersion the Minecraft version that this remote version suits. - * @param selfVersion the version string of the remote version. - * @param urls the installer or universal jar original URL. - */ - LegacyFabricAPIRemoteVersion(String gameVersion, String selfVersion, String fullVersion, Instant datePublished, RemoteAddon.Version version, List urls) { - super(GameComponentType.LEGACY_FABRIC_API, gameVersion, selfVersion, datePublished, urls); - - this.fullVersion = fullVersion; - this.version = version; - } - - @Override - public String getFullVersion() { - return fullVersion; - } - - public RemoteAddon.Version getVersion() { - return version; - } - - @Override - public Task getInstallTask( - DefaultDependencyManager dependencyManager, - GameInstanceManifest baseManifest, - Path modsDirectory) { - return new LegacyFabricAPIInstallTask(dependencyManager, baseManifest, this, modsDirectory); - } - - @Override - public int compareTo(ComponentRemoteVersion o) { - if (!(o instanceof LegacyFabricAPIRemoteVersion)) return 0; - return -this.getReleaseDate().compareTo(o.getReleaseDate()); - } -} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIVersionList.java deleted file mode 100644 index 9f9edb5fcd..0000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricAPIVersionList.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2022 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.download.legacyfabric; - -import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.download.ComponentVersionList; -import org.jackhuang.hmcl.addon.RemoteAddon; -import org.jackhuang.hmcl.addon.repository.ModrinthRemoteAddonRepository; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.Lang; - -import java.util.Collections; - -public class LegacyFabricAPIVersionList extends ComponentVersionList { - - private final DownloadProvider downloadProvider; - - public LegacyFabricAPIVersionList(DownloadProvider downloadProvider) { - this.downloadProvider = downloadProvider; - } - - @Override - public boolean hasType() { - return false; - } - - @Override - public Task refreshAsync() { - return Task.runAsync(() -> { - for (RemoteAddon.Version modVersion : Lang.toIterable(ModrinthRemoteAddonRepository.MODS.getRemoteVersionsById(downloadProvider, "legacy-fabric-api"))) { - for (String gameVersion : modVersion.gameVersions()) { - versions.put(gameVersion, new LegacyFabricAPIRemoteVersion(gameVersion, modVersion.version(), modVersion.name(), modVersion.datePublished(), modVersion, - Collections.singletonList(modVersion.file().url()))); - } - } - }); - } -} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricInstallTask.java index b5a592e8b1..906ab01351 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricInstallTask.java @@ -17,99 +17,27 @@ */ package org.jackhuang.hmcl.download.legacyfabric; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import org.jackhuang.hmcl.download.ComponentRemoteVersion; import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.download.fabric.FabricInstallTask; -import org.jackhuang.hmcl.game.*; -import org.jackhuang.hmcl.task.GetTask; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.gson.JsonUtils; +import org.jackhuang.hmcl.game.Artifact; +import org.jackhuang.hmcl.game.GameComponentType; +import org.jackhuang.hmcl.game.GameInstanceManifest; +import org.jackhuang.hmcl.game.GameInstancePatch; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +public final class LegacyFabricInstallTask extends FabricInstallTask { -public final class LegacyFabricInstallTask extends Task { - - private final DefaultDependencyManager dependencyManager; - private final GameInstanceManifest manifest; - private final LegacyFabricRemoteVersion remote; - private final GetTask launchMetaTask; - private final List> dependencies = new ArrayList<>(1); - - public LegacyFabricInstallTask(DefaultDependencyManager dependencyManager, GameInstanceManifest manifest, LegacyFabricRemoteVersion remoteVersion) { - this.dependencyManager = dependencyManager; - this.manifest = manifest; - this.remote = remoteVersion; - - launchMetaTask = new GetTask(dependencyManager.getDownloadProvider().injectURLsWithCandidates(remoteVersion.getUrls())); - launchMetaTask.setCacheRepository(dependencyManager.getCacheRepository()); - } - - @Override - public boolean doPreExecute() { - return true; - } - - @Override - public Collection> getDependents() { - return Collections.singleton(launchMetaTask); - } - - @Override - public Collection> getDependencies() { - return dependencies; + public LegacyFabricInstallTask(DefaultDependencyManager dependencyManager, GameInstanceManifest manifest, ComponentRemoteVersion remoteVersion) { + super(dependencyManager, manifest, remoteVersion); } - @Override - public boolean isRelyingOnDependencies() { - return false; + protected GameInstancePatch getPatch(FabricInfo legacyFabricInfo, String gameVersion, String loaderVersion) { + var patch = super.getPatch(legacyFabricInfo, gameVersion, loaderVersion); + return patch.withId(GameComponentType.LEGACY_FABRIC.getPatchId()); } @Override - public void execute() { - setResult(getPatch(JsonUtils.GSON.fromJson(launchMetaTask.getResult(), FabricInstallTask.FabricInfo.class), remote.getGameVersion(), remote.getSelfVersion())); - - dependencies.add(new org.jackhuang.hmcl.download.game.GameLibrariesTask(dependencyManager, manifest, true, getResult().getLibraries())); - } - - private GameInstancePatch getPatch(FabricInstallTask.FabricInfo legacyFabricInfo, String gameVersion, String loaderVersion) { - JsonObject launcherMeta = legacyFabricInfo.getLauncherMeta(); - Arguments arguments = new Arguments(); - - String mainClass; - if (!launcherMeta.get("mainClass").isJsonObject()) { - mainClass = launcherMeta.get("mainClass").getAsString(); - } else { - mainClass = launcherMeta.get("mainClass").getAsJsonObject().get("client").getAsString(); - } - - if (launcherMeta.has("launchwrapper")) { - String clientTweaker = launcherMeta.get("launchwrapper").getAsJsonObject().get("tweakers").getAsJsonObject().get("client").getAsJsonArray().get(0).getAsString(); - arguments = arguments.addGameArguments("--tweakClass", clientTweaker); - } - - JsonObject librariesObject = launcherMeta.getAsJsonObject("libraries"); - List libraries = new ArrayList<>(); - - // "common, server" is hard coded in fabric installer. - // Don't know the purpose of ignoring client libraries. - for (String side : new String[]{"common", "server"}) { - for (JsonElement element : librariesObject.getAsJsonArray(side)) { - libraries.add(JsonUtils.GSON.fromJson(element, Library.class)); - } - } - - // libraries.add(new Library(Artifact.fromDescriptor(legacyFabricInfo.hashed.maven), getMavenRepositoryByGroup(legacyFabricInfo.hashed.maven), null)); - libraries.add(new Library(Artifact.fromDescriptor(legacyFabricInfo.getIntermediary().getMaven()), getMavenRepositoryByGroup(legacyFabricInfo.getIntermediary().getMaven()), null)); - libraries.add(new Library(Artifact.fromDescriptor(legacyFabricInfo.getLoader().getMaven()), getMavenRepositoryByGroup(legacyFabricInfo.getLoader().getMaven()), null)); - - return new GameInstancePatch(GameComponentType.LEGACY_FABRIC.getPatchId(), loaderVersion, GameInstancePatch.PRIORITY_LOADER, arguments, mainClass, libraries); - } - - private static String getMavenRepositoryByGroup(String maven) { + protected String getMavenRepositoryByGroup(String maven) { Artifact artifact = Artifact.fromDescriptor(maven); return switch (artifact.getGroup()) { case "net.fabricmc" -> "https://maven.fabricmc.net/"; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricVersionList.java index a6c336620f..0b95c27ac0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/legacyfabric/LegacyFabricVersionList.java @@ -18,73 +18,37 @@ package org.jackhuang.hmcl.download.legacyfabric; import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.download.ComponentVersionList; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.gson.JsonSerializable; -import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.NetworkUtils; +import org.jackhuang.hmcl.download.fabriclike.FabricLikeVersionList; -import java.io.IOException; -import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; - -import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf; - -public final class LegacyFabricVersionList extends ComponentVersionList { - private final DownloadProvider downloadProvider; +public final class LegacyFabricVersionList extends FabricLikeVersionList { public LegacyFabricVersionList(DownloadProvider downloadProvider) { - this.downloadProvider = downloadProvider; + super(downloadProvider); } @Override - public boolean hasType() { - return false; + protected String getLoaderMetaURL() { + return "https://meta.legacyfabric.net/v2/versions/loader"; } @Override - public Task refreshAsync() { - return Task.runAsync(() -> { - List gameVersions = getGameVersions(GAME_META_URL); - List loaderVersions = getGameVersions(LOADER_META_URL); - - lock.writeLock().lock(); - - try { - for (String metaGameVersion : gameVersions) { - String gameVersion = normalizeVersion(metaGameVersion); - for (String loaderVersion : loaderVersions) { - versions.put(gameVersion, new LegacyFabricRemoteVersion(gameVersion, loaderVersion, - Collections.singletonList(getLaunchMetaUrl(metaGameVersion, loaderVersion)))); - } - } - } finally { - lock.writeLock().unlock(); - } - }); - } - - private static final String LOADER_META_URL = "https://meta.legacyfabric.net/v2/versions/loader"; - private static final String GAME_META_URL = "https://meta.legacyfabric.net/v2/versions/game"; - - private List getGameVersions(String metaUrl) throws IOException { - String json = NetworkUtils.doGet(downloadProvider.injectURLWithCandidates(metaUrl)); - return JsonUtils.GSON.fromJson(json, listTypeOf(GameVersion.class)) - .stream().map(GameVersion::version).collect(Collectors.toList()); + protected String getGameMetaURL() { + return "https://meta.legacyfabric.net/v2/versions/game"; } - private static String normalizeVersion(String version) { - return version.startsWith("2point0_") - ? "2.0_" + version.substring("2point0_".length()) - : version; + @Override + protected String getLaunchMetaUrl(String gameVersion, String loaderVersion) { + return String.format("https://meta.legacyfabric.net/v2/versions/loader/%s/%s", gameVersion, loaderVersion); } - private static String getLaunchMetaUrl(String gameVersion, String loaderVersion) { - return String.format("https://meta.legacyfabric.net/v2/versions/loader/%s/%s", gameVersion, loaderVersion); + @Override + protected LegacyFabricRemoteVersion createRemoteVersion(String gameVersion, String loaderVersion, List urls) { + return new LegacyFabricRemoteVersion(gameVersion, loaderVersion, urls); } - @JsonSerializable - private record GameVersion(String version, String maven, boolean stable) { + @Override + protected String normalizeVersion(String version) { + return version.startsWith("2point0_") ? "2.0_" + version.substring("2point0_".length()) : version; } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIInstallTask.java deleted file mode 100644 index e78a65ca59..0000000000 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltAPIInstallTask.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2021 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.download.quilt; - -import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.game.GameInstanceManifest; -import org.jackhuang.hmcl.game.GameInstancePatch; -import org.jackhuang.hmcl.task.FileDownloadTask; -import org.jackhuang.hmcl.task.Task; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Note: Quilt should be installed first. - * - * @author huangyuhui - */ -public final class QuiltAPIInstallTask extends Task { - - private final DefaultDependencyManager dependencyManager; - private final GameInstanceManifest manifest; - private final QuiltAPIRemoteVersion remote; - private final Path modsDirectory; - private final List> dependencies = new ArrayList<>(1); - - /// @param dependencyManager the dependency manager - /// @param manifest the manifest being installed into - /// @param remoteVersion the Quilt API remote version - /// @param modsDirectory the target mods directory (must already be resolved by the caller) - public QuiltAPIInstallTask( - DefaultDependencyManager dependencyManager, - GameInstanceManifest manifest, - QuiltAPIRemoteVersion remoteVersion, - Path modsDirectory) { - this.dependencyManager = dependencyManager; - this.manifest = manifest; - this.remote = remoteVersion; - this.modsDirectory = modsDirectory; - } - - @Override - public Collection> getDependencies() { - return dependencies; - } - - @Override - public boolean isRelyingOnDependencies() { - return false; - } - - @Override - public void execute() throws IOException { - dependencies.add(new FileDownloadTask( - remote.getVersion().file().url(), - modsDirectory.resolve("quilt-api-" + remote.getVersion().version() + ".jar"), - remote.getVersion().file().getIntegrityCheck()) - ); - } -} diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltInstallTask.java index bc94a6cb79..0e8668ff32 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltInstallTask.java @@ -17,209 +17,37 @@ */ package org.jackhuang.hmcl.download.quilt; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import org.jackhuang.hmcl.download.ComponentRemoteVersion; import org.jackhuang.hmcl.download.DefaultDependencyManager; -import org.jackhuang.hmcl.download.UnsupportedInstallationException; -import org.jackhuang.hmcl.game.*; -import org.jackhuang.hmcl.task.GetTask; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.gson.JsonSerializable; -import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -import static org.jackhuang.hmcl.download.UnsupportedInstallationException.FABRIC_NOT_COMPATIBLE_WITH_FORGE; +import org.jackhuang.hmcl.download.fabric.FabricInstallTask; +import org.jackhuang.hmcl.game.Artifact; +import org.jackhuang.hmcl.game.GameComponentType; +import org.jackhuang.hmcl.game.GameInstanceManifest; +import org.jackhuang.hmcl.game.GameInstancePatch; /** * Note: Quilt should be installed first. * * @author huangyuhui */ -public final class QuiltInstallTask extends Task { - - private final DefaultDependencyManager dependencyManager; - private final GameInstanceManifest manifest; - private final QuiltRemoteVersion remote; - private final GetTask launchMetaTask; - private final List> dependencies = new ArrayList<>(1); - - public QuiltInstallTask(DefaultDependencyManager dependencyManager, GameInstanceManifest manifest, QuiltRemoteVersion remoteVersion) { - this.dependencyManager = dependencyManager; - this.manifest = manifest; - this.remote = remoteVersion; - - launchMetaTask = new GetTask(dependencyManager.getDownloadProvider().injectURLsWithCandidates(remoteVersion.getUrls())); - launchMetaTask.setCacheRepository(dependencyManager.getCacheRepository()); - } - - @Override - public boolean doPreExecute() { - return true; - } - - @Override - public void preExecute() throws Exception { - if (!Objects.equals(GameComponentAnalyzer.VANILLA_MAIN, manifest.mainClass())) - throw new UnsupportedInstallationException(FABRIC_NOT_COMPATIBLE_WITH_FORGE); - } +public final class QuiltInstallTask extends FabricInstallTask { - @Override - public Collection> getDependents() { - return Collections.singleton(launchMetaTask); - } - - @Override - public Collection> getDependencies() { - return dependencies; + public QuiltInstallTask(DefaultDependencyManager dependencyManager, GameInstanceManifest manifest, ComponentRemoteVersion remoteVersion) { + super(dependencyManager, manifest, remoteVersion); } - @Override - public boolean isRelyingOnDependencies() { - return false; + protected GameInstancePatch getPatch(FabricInfo legacyFabricInfo, String gameVersion, String loaderVersion) { + var patch = super.getPatch(legacyFabricInfo, gameVersion, loaderVersion); + return patch.withId(GameComponentType.LEGACY_FABRIC.getPatchId()); } @Override - public void execute() { - setResult(getPatch(JsonUtils.GSON.fromJson(launchMetaTask.getResult(), QuiltInfo.class), remote.getSelfVersion())); - - dependencies.add(new org.jackhuang.hmcl.download.game.GameLibrariesTask(dependencyManager, manifest, true, getResult().getLibraries())); - } - - /// Creates the Quilt patch represented by the installer metadata. - private static GameInstancePatch getPatch(QuiltInfo quiltInfo, String loaderVersion) { - JsonObject launcherMeta = quiltInfo.launcherMeta; - Arguments arguments = new Arguments(); - - String mainClass; - if (!launcherMeta.get("mainClass").isJsonObject()) { - mainClass = launcherMeta.get("mainClass").getAsString(); - } else { - mainClass = launcherMeta.get("mainClass").getAsJsonObject().get("client").getAsString(); - } - - if (launcherMeta.has("launchwrapper")) { - String clientTweaker = launcherMeta.get("launchwrapper").getAsJsonObject().get("tweakers").getAsJsonObject().get("client").getAsJsonArray().get(0).getAsString(); - arguments = arguments.addGameArguments("--tweakClass", clientTweaker); - } - - JsonObject librariesObject = launcherMeta.getAsJsonObject("libraries"); - List libraries = new ArrayList<>(); - - // "common, server" is hard coded in fabric installer. - // Don't know the purpose of ignoring client libraries. - for (String side : new String[]{"common", "server"}) { - for (JsonElement element : librariesObject.getAsJsonArray(side)) { - libraries.add(JsonUtils.GSON.fromJson(element, Library.class)); - } - } - - // libraries.add(new Library(Artifact.fromDescriptor(quiltInfo.hashed.maven), getMavenRepositoryByGroup(quiltInfo.hashed.maven), null)); - if (quiltInfo.intermediary != null) { - libraries.add(new Library(Artifact.fromDescriptor(quiltInfo.intermediary.maven), getMavenRepositoryByGroup(quiltInfo.intermediary.maven), null)); - } - libraries.add(new Library(Artifact.fromDescriptor(quiltInfo.loader.maven), getMavenRepositoryByGroup(quiltInfo.loader.maven), null)); - - return new GameInstancePatch(GameComponentType.QUILT.getPatchId(), loaderVersion, GameInstancePatch.PRIORITY_LOADER, arguments, mainClass, libraries); - } - - private static String getMavenRepositoryByGroup(String maven) { + protected String getMavenRepositoryByGroup(String maven) { Artifact artifact = Artifact.fromDescriptor(maven); - switch (artifact.getGroup()) { - case "net.fabricmc": - return "https://maven.fabricmc.net/"; - case "org.quiltmc": - return "https://maven.quiltmc.org/repository/release/"; - default: - return "https://maven.fabricmc.net/"; - } - } - - @JsonSerializable - public static class QuiltInfo { - private final LoaderInfo loader; - private final @Nullable IntermediaryInfo hashed; - private final @Nullable IntermediaryInfo intermediary; - private final JsonObject launcherMeta; - - public QuiltInfo(LoaderInfo loader, @Nullable IntermediaryInfo hashed, @Nullable IntermediaryInfo intermediary, JsonObject launcherMeta) { - this.loader = loader; - this.hashed = hashed; - this.intermediary = intermediary; - this.launcherMeta = launcherMeta; - } - - public LoaderInfo getLoader() { - return loader; - } - - public @Nullable IntermediaryInfo getHashed() { - return hashed; - } - - public @Nullable IntermediaryInfo getIntermediary() { - return intermediary; - } - - public JsonObject getLauncherMeta() { - return launcherMeta; - } - } - - @JsonSerializable - public static class LoaderInfo { - private final String separator; - private final int build; - private final String maven; - private final String version; - private final boolean stable; - - public LoaderInfo(String separator, int build, String maven, String version, boolean stable) { - this.separator = separator; - this.build = build; - this.maven = maven; - this.version = version; - this.stable = stable; - } - - public String getSeparator() { - return separator; - } - - public int getBuild() { - return build; - } - - public String getMaven() { - return maven; - } - - public String getVersion() { - return version; - } - - public boolean isStable() { - return stable; - } - } - - @JsonSerializable - public static class IntermediaryInfo { - private final String maven; - private final String version; - - public IntermediaryInfo(String maven, String version) { - this.maven = maven; - this.version = version; - } - - public String getMaven() { - return maven; - } - - public String getVersion() { - return version; - } + return switch (artifact.getGroup()) { + case "net.fabricmc" -> "https://maven.fabricmc.net/"; + case "org.quiltmc" -> "https://maven.quiltmc.org/repository/release/"; + default -> "https://maven.fabricmc.net/"; + }; } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltVersionList.java index 879f5957e9..1fa14dcc78 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/quilt/QuiltVersionList.java @@ -18,64 +18,32 @@ package org.jackhuang.hmcl.download.quilt; import org.jackhuang.hmcl.download.DownloadProvider; -import org.jackhuang.hmcl.download.ComponentVersionList; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.gson.JsonSerializable; -import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.NetworkUtils; +import org.jackhuang.hmcl.download.fabriclike.FabricLikeVersionList; -import java.io.IOException; -import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; - -import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf; - -public final class QuiltVersionList extends ComponentVersionList { - private final DownloadProvider downloadProvider; +public final class QuiltVersionList extends FabricLikeVersionList { public QuiltVersionList(DownloadProvider downloadProvider) { - this.downloadProvider = downloadProvider; + super(downloadProvider); } @Override - public boolean hasType() { - return false; + protected String getLoaderMetaURL() { + return "https://meta.quiltmc.org/v3/versions/loader"; } @Override - public Task refreshAsync() { - return Task.runAsync(() -> { - List gameVersions = getGameVersions(GAME_META_URL); - List loaderVersions = getGameVersions(LOADER_META_URL); - - lock.writeLock().lock(); - - try { - for (String gameVersion : gameVersions) - for (String loaderVersion : loaderVersions) - versions.put(gameVersion, new QuiltRemoteVersion(gameVersion, loaderVersion, - Collections.singletonList(getLaunchMetaUrl(gameVersion, loaderVersion)))); - } finally { - lock.writeLock().unlock(); - } - }); + protected String getGameMetaURL() { + return "https://meta.quiltmc.org/v3/versions/game"; } - private static final String LOADER_META_URL = "https://meta.quiltmc.org/v3/versions/loader"; - private static final String GAME_META_URL = "https://meta.quiltmc.org/v3/versions/game"; - - private List getGameVersions(String metaUrl) throws IOException { - String json = NetworkUtils.doGet(downloadProvider.injectURLWithCandidates(metaUrl)); - return JsonUtils.GSON.fromJson(json, listTypeOf(GameVersion.class)) - .stream().map(GameVersion::version).collect(Collectors.toList()); - } - - private static String getLaunchMetaUrl(String gameVersion, String loaderVersion) { + @Override + protected String getLaunchMetaUrl(String gameVersion, String loaderVersion) { return String.format("https://meta.quiltmc.org/v3/versions/loader/%s/%s", gameVersion, loaderVersion); } - @JsonSerializable - private record GameVersion(String version, String maven, boolean stable) { + @Override + protected QuiltRemoteVersion createRemoteVersion(String gameVersion, String loaderVersion, List urls) { + return new QuiltRemoteVersion(gameVersion, loaderVersion, urls); } }