feat: Cleanroom 自动安装 (#4272)

Co-authored-by: Zkitefly <64117916+zkitefly@users.noreply.github.com>
Co-authored-by: Glavo <zjx001202@gmail.com>
This commit is contained in:
辞庐
2025-09-03 15:50:57 +08:00
committed by GitHub
parent ce24e4e622
commit e8813fe153
25 changed files with 267 additions and 11 deletions

BIN
HMCL/image/cleanroom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -314,6 +314,8 @@ public class HMCLGameRepository extends DefaultGameRepository {
return VersionIconType.FABRIC.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.FORGE))
return VersionIconType.FORGE.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.CLEANROOM))
return VersionIconType.CLEANROOM.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.NEO_FORGE))
return VersionIconType.NEO_FORGE.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.QUILT))

View File

@@ -34,7 +34,8 @@ public enum VersionIconType {
NEO_FORGE("/assets/img/neoforge.png"),
FURNACE("/assets/img/furnace.png"),
QUILT("/assets/img/quilt.png"),
APRIL_FOOLS("/assets/img/april_fools.png");
APRIL_FOOLS("/assets/img/april_fools.png"),
CLEANROOM("/assets/img/cleanroom.png");
// Please append new items at last

View File

@@ -138,6 +138,9 @@ public class InstallerItem extends Control {
case "forge":
iconType = VersionIconType.FORGE;
break;
case "cleanroom":
iconType = VersionIconType.CLEANROOM;
break;
case "liteloader":
iconType = VersionIconType.CHICKEN;
break;
@@ -232,6 +235,7 @@ public class InstallerItem extends Control {
InstallerItem fabric = new InstallerItem(FABRIC, style);
InstallerItem fabricApi = new InstallerItem(FABRIC_API, style);
InstallerItem forge = new InstallerItem(FORGE, style);
InstallerItem cleanroom = new InstallerItem(CLEANROOM, style);
InstallerItem neoForge = new InstallerItem(NEO_FORGE, style);
InstallerItem liteLoader = new InstallerItem(LITELOADER, style);
InstallerItem optiFine = new InstallerItem(OPTIFINE, style);
@@ -239,11 +243,11 @@ public class InstallerItem extends Control {
InstallerItem quiltApi = new InstallerItem(QUILT_API, style);
Map<InstallerItem, Set<InstallerItem>> incompatibleMap = new HashMap<>();
mutualIncompatible(incompatibleMap, forge, fabric, quilt, neoForge);
addIncompatibles(incompatibleMap, liteLoader, fabric, quilt, neoForge);
addIncompatibles(incompatibleMap, optiFine, fabric, quilt, neoForge);
addIncompatibles(incompatibleMap, fabricApi, forge, quiltApi, neoForge, liteLoader, optiFine);
addIncompatibles(incompatibleMap, quiltApi, forge, fabric, fabricApi, neoForge, liteLoader, optiFine);
mutualIncompatible(incompatibleMap, forge, fabric, quilt, neoForge, cleanroom);
addIncompatibles(incompatibleMap, liteLoader, fabric, quilt, neoForge, cleanroom);
addIncompatibles(incompatibleMap, optiFine, fabric, quilt, neoForge, cleanroom);
addIncompatibles(incompatibleMap, fabricApi, forge, quiltApi, neoForge, liteLoader, optiFine, cleanroom);
addIncompatibles(incompatibleMap, quiltApi, forge, fabric, fabricApi, neoForge, liteLoader, optiFine, cleanroom);
for (Map.Entry<InstallerItem, Set<InstallerItem>> entry : incompatibleMap.entrySet()) {
InstallerItem item = entry.getKey();
@@ -277,7 +281,7 @@ public class InstallerItem extends Control {
game.versionProperty.set(new InstalledState(gameVersion, false, false));
}
InstallerItem[] all = {game, forge, neoForge, liteLoader, optiFine, fabric, fabricApi, quilt, quiltApi};
InstallerItem[] all = {game, forge, neoForge, liteLoader, optiFine, fabric, fabricApi, quilt, quiltApi, cleanroom};
for (InstallerItem item : all) {
if (!item.resolvedStateProperty.isBound()) {
@@ -293,6 +297,8 @@ public class InstallerItem extends Control {
if (gameVersion == null) {
this.libraries = all;
} else if (gameVersion.equals("1.12.2")) {
this.libraries = new InstallerItem[]{game, forge, cleanroom, liteLoader, optiFine};
} else if (GameVersionNumber.compare(gameVersion, "1.13") < 0) {
this.libraries = new InstallerItem[]{game, forge, liteLoader, optiFine};
} else {

View File

@@ -33,6 +33,7 @@ import javafx.scene.control.ListCell;
import javafx.scene.control.ProgressIndicator;
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.forge.ForgeNewInstallTask;
@@ -164,6 +165,8 @@ public final class TaskListPane extends StackPane {
if (task.getInheritedStage() != null && task.getInheritedStage().startsWith("hmcl.install.game"))
return;
task.setName(i18n("install.installer.install", i18n("install.installer.game")));
} else if (task instanceof CleanroomInstallTask) {
task.setName(i18n("install.installer.install", i18n("install.installer.cleanroom")));
} 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) {
@@ -439,6 +442,7 @@ public final class TaskListPane extends StackPane {
case "hmcl.install.libraries": message = i18n("libraries.download"); break;
case "hmcl.install.game": message = i18n("install.installer.install", i18n("install.installer.game") + " " + stageValue); break;
case "hmcl.install.forge": message = i18n("install.installer.install", i18n("install.installer.forge") + " " + stageValue); break;
case "hmcl.install.cleanroom": message = i18n("install.installer.install", i18n("install.installer.cleanroom") + " " + stageValue); break;
case "hmcl.install.neoforge": message = i18n("install.installer.install", i18n("install.installer.neoforge") + " " + stageValue); break;
case "hmcl.install.liteloader": message = i18n("install.installer.install", i18n("install.installer.liteloader") + " " + stageValue); break;
case "hmcl.install.optifine": message = i18n("install.installer.install", i18n("install.installer.optifine") + " " + stageValue); break;

View File

@@ -130,6 +130,9 @@ public class InstallersPage extends AbstractInstallersPage {
case NEO_FORGE:
loaderName = i18n("install.installer.neoforge");
break;
case CLEANROOM:
loaderName = i18n("install.installer.cleanroom");
break;
case FABRIC:
loaderName = i18n("install.installer.fabric");
break;

View File

@@ -31,6 +31,7 @@ import javafx.scene.layout.*;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.download.RemoteVersion;
import org.jackhuang.hmcl.download.VersionList;
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.forge.ForgeRemoteVersion;
@@ -220,6 +221,8 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
iconType = VersionIconType.OPTIFINE;
else if (remoteVersion instanceof ForgeRemoteVersion)
iconType = VersionIconType.FORGE;
else if (remoteVersion instanceof CleanroomRemoteVersion)
iconType = VersionIconType.CLEANROOM;
else if (remoteVersion instanceof NeoForgeRemoteVersion)
iconType = VersionIconType.NEO_FORGE;
else if (remoteVersion instanceof FabricRemoteVersion || remoteVersion instanceof FabricAPIRemoteVersion)

View File

@@ -407,6 +407,9 @@ public class DownloadPage extends Control implements DecoratorPage {
case FORGE:
content.getTags().add(i18n("install.installer.forge"));
break;
case CLEANROOM:
content.getTags().add(i18n("install.installer.cleanroom"));
break;
case NEO_FORGED:
content.getTags().add(i18n("install.installer.neoforge"));
break;

View File

@@ -76,7 +76,7 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
InstallerItem.InstallerItemGroup group = new InstallerItem.InstallerItemGroup(gameVersion, InstallerItem.Style.LIST_ITEM);
// Conventional libraries: game, fabric, forge, neoforge, liteloader, optifine
// Conventional libraries: game, fabric, forge, cleanroom, neoforge, liteloader, optifine
for (InstallerItem item : group.getLibraries()) {
String libraryId = item.getLibraryId();

View File

@@ -424,6 +424,9 @@ class ModListPageSkin extends SkinBase<ModListPage> {
case FORGE:
loaderName = i18n("install.installer.forge");
break;
case CLEANROOM:
loaderName = i18n("install.installer.cleanroom");
break;
case NEO_FORGED:
loaderName = i18n("install.installer.neoforge");
break;
@@ -550,6 +553,9 @@ class ModListPageSkin extends SkinBase<ModListPage> {
case FORGE:
content.getTags().add(i18n("install.installer.forge"));
break;
case CLEANROOM:
content.getTags().add(i18n("install.installer.cleanroom"));
break;
case NEO_FORGED:
content.getTags().add(i18n("install.installer.neoforge"));
break;

View File

@@ -65,6 +65,7 @@ public class VersionIconDialog extends DialogPane {
createIcon(VersionIconType.CRAFT_TABLE),
createIcon(VersionIconType.FABRIC),
createIcon(VersionIconType.FORGE),
createIcon(VersionIconType.CLEANROOM),
createIcon(VersionIconType.NEO_FORGE),
createIcon(VersionIconType.FURNACE),
createIcon(VersionIconType.QUILT)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -701,6 +701,7 @@ install.failed.optifine_forge_1.17=For Minecraft 1.17.1, Forge is only compatibl
install.failed.version_mismatch=This loader requires the game version %s, but the installed one is %s.
install.installer.change_version=%s Incompatible
install.installer.choose=Choose Your %s Version
install.installer.cleanroom=Cleanroom
install.installer.depend=Requires %s
install.installer.do_not_install=Do not install
install.installer.fabric=Fabric

View File

@@ -510,6 +510,7 @@ install.failed.optifine_forge_1.17=對於 Minecraft 1.17.1 版本,僅 OptiFine
install.failed.version_mismatch=該載入器需要的遊戲版本為 %s但實際的遊戲版本為 %s。
install.installer.change_version=%s 與目前遊戲不相容,請更換版本
install.installer.choose=選取 %s 版本
install.installer.cleanroom=Cleanroom
install.installer.depend=需要先安裝 %s
install.installer.do_not_install=不安裝
install.installer.fabric=Fabric

View File

@@ -520,6 +520,7 @@ install.failed.optifine_forge_1.17=对于 Minecraft 1.17.1 版本,仅 OptiFine
install.failed.version_mismatch=该组件需要的游戏版本为 %s但实际的游戏版本为 %s。
install.installer.change_version=%s 与当前游戏不兼容,请更换版本
install.installer.choose=选择 %s 版本
install.installer.cleanroom=Cleanroom
install.installer.depend=需要先安装 %s
install.installer.do_not_install=不安装
install.installer.fabric=Fabric
@@ -1053,6 +1054,7 @@ settings.advanced.custom_commands.hint=自定义命令被调用时将包含如
\ · $INST_JAVA: 游戏运行使用的 Java 路径;\n\
\ · $INST_FORGE: 若安装了 Forge将会存在本环境变量\n\
\ · $INST_NEOFORGE: 若安装了 NeoForge将会存在本环境变量\n\
\ · $INST_CLEANROOM: 若安装了 Cleanroom将会存在本环境变量\n\
\ · $INST_LITELOADER: 若安装了 LiteLoader将会存在本环境变量\n\
\ · $INST_OPTIFINE: 若安装了 OptiFine将会存在本环境变量\n\
\ · $INST_FABRIC: 若安装了 Fabric将会存在本环境变量\n\