diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SVG.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SVG.java index 6666e7380..c5b1b1b25 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SVG.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SVG.java @@ -408,4 +408,16 @@ public final class SVG { "M21 2H3C1.9 2 1 2.9 1 4V20C1 21.1 1.9 22 3 22H21C22.1 22 23 21.1 23 20V4C23 2.9 22.1 2 21 2M21 20H3V6H21V20Z", fill, width, height); } + + public static Node earth(ObjectBinding fill, double width, double height) { + return createSVGPath( + "M17.9,17.39C17.64,16.59 16.89,16 16,16H15V13A1,1 0 0,0 14,12H8V10H10A1,1 0 0,0 11,9V7H13A2,2 0 0,0 15,5V4.59C17.93,5.77 20,8.64 20,12C20,14.08 19.2,15.97 17.9,17.39M11,19.93C7.05,19.44 4,16.08 4,12C4,11.38 4.08,10.78 4.21,10.21L9,15V16A2,2 0 0,0 11,18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z", + fill, width, height); + } + + public static Node contentSaveMoveOutline(ObjectBinding fill, double width, double height) { + return createSVGPath( + "M13 17H17V14L22 18.5L17 23V20H13V17M14 12.8C13.5 12.31 12.78 12 12 12C10.34 12 9 13.34 9 15C9 16.31 9.84 17.41 11 17.82C11.07 15.67 12.27 13.8 14 12.8M11.09 19H5V5H16.17L19 7.83V12.35C19.75 12.61 20.42 13 21 13.54V7L17 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H11.81C11.46 20.39 11.21 19.72 11.09 19M6 10H15V6H6V10Z", + fill, width, height); + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java index 7da1ac6e5..150158c3e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java @@ -55,15 +55,19 @@ public class DownloadPage extends BorderPane implements DecoratorPage { private final TabHeader.Tab modTab = new TabHeader.Tab<>("modTab"); private final TabHeader.Tab modpackTab = new TabHeader.Tab<>("modpackTab"); private final TabHeader.Tab resourcePackTab = new TabHeader.Tab<>("resourcePackTab"); + private final TabHeader.Tab customizationTab = new TabHeader.Tab<>("customizationTab"); + private final TabHeader.Tab worldTab = new TabHeader.Tab<>("worldTab"); private final TransitionPane transitionPane = new TransitionPane(); private WeakListenerHolder listenerHolder; public DownloadPage() { - modTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MODPACK, Versions::downloadModpackImpl)); - modpackTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MOD, this::download)); - resourcePackTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MOD, this::download)); - tab = new TabHeader(modTab, modpackTab, resourcePackTab); + modpackTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MODPACK, Versions::downloadModpackImpl)); + modTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MOD, (profile, version, file) -> download(profile, version, file, "mods"))); + resourcePackTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_RESOURCE_PACK, (profile, version, file) -> download(profile, version, file, "resourcepacks"))); +// customizationTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_CUSTOMIZATION, this::download)); + worldTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_WORLD)); + tab = new TabHeader(modpackTab, modTab, resourcePackTab, worldTab); Profiles.registerVersionsListener(this::loadVersions); @@ -71,7 +75,7 @@ public class DownloadPage extends BorderPane implements DecoratorPage { FXUtils.onChangeAndOperate(tab.getSelectionModel().selectedItemProperty(), newValue -> { if (newValue.initializeIfNeeded()) { if (newValue.getNode() instanceof VersionPage.VersionLoadable) { - ((VersionPage.VersionLoadable) newValue.getNode()).loadVersion(Profiles.getSelectedProfile(), Profiles.getSelectedVersion()); + ((VersionPage.VersionLoadable) newValue.getNode()).loadVersion(Profiles.getSelectedProfile(), null); } } transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer()); @@ -79,6 +83,12 @@ public class DownloadPage extends BorderPane implements DecoratorPage { { AdvancedListBox sideBar = new AdvancedListBox() + .addNavigationDrawerItem(item -> { + item.setTitle(i18n("install.new_game")); + item.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20))); + item.setOnAction(e -> Versions.addNewGame()); + }) + .startCategory(i18n("download")) .addNavigationDrawerItem(item -> { item.setTitle(i18n("mods")); item.setLeftGraphic(wrap(SVG.puzzle(null, 20, 20))); @@ -97,10 +107,17 @@ public class DownloadPage extends BorderPane implements DecoratorPage { item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(resourcePackTab)); item.setOnAction(e -> tab.getSelectionModel().select(resourcePackTab)); }) +// .addNavigationDrawerItem(item -> { +// item.setTitle(i18n("download.curseforge.customization")); +// item.setLeftGraphic(wrap(SVG.script(null, 20, 20))); +// item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(customizationTab)); +// item.setOnAction(e -> tab.getSelectionModel().select(customizationTab)); +// }) .addNavigationDrawerItem(item -> { - item.setTitle(i18n("install.new_game")); - item.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20))); - item.setOnAction(e -> Versions.addNewGame()); + item.setTitle(i18n("world")); + item.setLeftGraphic(wrap(SVG.earth(null, 20, 20))); + item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(worldTab)); + item.setOnAction(e -> tab.getSelectionModel().select(worldTab)); }); FXUtils.setLimitWidth(sideBar, 200); setLeft(sideBar); @@ -109,12 +126,11 @@ public class DownloadPage extends BorderPane implements DecoratorPage { setCenter(transitionPane); } - private void download(Profile profile, @Nullable String version, CurseAddon.LatestFile file) { - if (version == null) { - throw new InternalError(); - } + private void download(Profile profile, @Nullable String version, CurseAddon.LatestFile file, String subdirectoryName) { + if (version == null) version = profile.getSelectedVersion(); - Path dest = profile.getRepository().getRunDirectory(version).toPath().resolve("mods").resolve(file.getFileName()); + Path runDirectory = profile.getRepository().hasVersion(version) ? profile.getRepository().getRunDirectory(version).toPath() : profile.getRepository().getBaseDirectory().toPath(); + Path dest = runDirectory.resolve(subdirectoryName).resolve(file.getFileName()); TaskExecutorDialogPane downloadingPane = new TaskExecutorDialogPane(it -> { }); @@ -134,19 +150,21 @@ public class DownloadPage extends BorderPane implements DecoratorPage { WeakListenerHolder listenerHolder = new WeakListenerHolder(); runInFX(() -> { if (profile == Profiles.getSelectedProfile()) { - profile.selectedVersionProperty().addListener(listenerHolder.weak((a, b, newValue) -> { - FXUtils.checkFxUserThread(); - - if (modTab.isInitialized()) { - modTab.getNode().loadVersion(profile, newValue); - } - if (modpackTab.isInitialized()) { - modpackTab.getNode().loadVersion(profile, newValue); - } - if (resourcePackTab.isInitialized()) { - resourcePackTab.getNode().loadVersion(profile, newValue); - } - })); + if (modTab.isInitialized()) { + modTab.getNode().loadVersion(profile, null); + } + if (modpackTab.isInitialized()) { + modpackTab.getNode().loadVersion(profile, null); + } + if (resourcePackTab.isInitialized()) { + resourcePackTab.getNode().loadVersion(profile, null); + } + if (customizationTab.isInitialized()) { + customizationTab.getNode().loadVersion(profile, null); + } + if (worldTab.isInitialized()) { + worldTab.getNode().loadVersion(profile, null); + } } }); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadListPage.java index 2f6efb104..48ee01267 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadListPage.java @@ -56,6 +56,7 @@ public class ModDownloadListPage extends Control implements DecoratorPage, Versi private final ObjectProperty version = new SimpleObjectProperty<>(); private final ListProperty items = new SimpleListProperty<>(this, "items", FXCollections.observableArrayList()); private final ModDownloadPage.DownloadCallback callback; + private boolean searchInitialized = false; /** * @see org.jackhuang.hmcl.mod.curse.CurseModManager#SECTION_MODPACK @@ -63,6 +64,10 @@ public class ModDownloadListPage extends Control implements DecoratorPage, Versi */ private final int section; + public ModDownloadListPage(int section) { + this(section, null); + } + public ModDownloadListPage(int section, ModDownloadPage.DownloadCallback callback) { this.section = section; this.callback = callback; @@ -74,6 +79,11 @@ public class ModDownloadListPage extends Control implements DecoratorPage, Versi setLoading(false); setFailed(false); + + if (!searchInitialized) { + searchInitialized = true; + search("", 0, 0, "", 0); + } } public boolean isFailed() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadPage.java index ce28cd5b0..e7abf648c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModDownloadPage.java @@ -29,13 +29,19 @@ import javafx.scene.control.Skin; import javafx.scene.control.SkinBase; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.layout.*; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; +import javafx.stage.FileChooser; import org.jackhuang.hmcl.game.GameVersion; import org.jackhuang.hmcl.mod.curse.CurseAddon; import org.jackhuang.hmcl.mod.curse.CurseModManager; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Theme; +import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.construct.FloatListCell; @@ -43,6 +49,7 @@ import org.jackhuang.hmcl.ui.construct.SpinnerPane; import org.jackhuang.hmcl.ui.construct.TwoLineListItem; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.util.StringUtils; +import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -66,7 +73,7 @@ public class ModDownloadPage extends Control implements DecoratorPage { private final Profile.ProfileVersion version; private final DownloadCallback callback; - public ModDownloadPage(CurseAddon addon, Profile.ProfileVersion version, DownloadCallback callback) { + public ModDownloadPage(CurseAddon addon, Profile.ProfileVersion version, @Nullable DownloadCallback callback) { this.addon = addon; this.version = version; this.callback = callback; @@ -91,7 +98,7 @@ public class ModDownloadPage extends Control implements DecoratorPage { items.setAll(files); }).start(); - this.state.set(State.fromTitle(i18n("mods.download.title", addon.getName()))); + this.state.set(State.fromTitle(addon.getName())); } public CurseAddon getAddon() { @@ -127,7 +134,29 @@ public class ModDownloadPage extends Control implements DecoratorPage { } public void download(CurseAddon.LatestFile file) { - this.callback.download(version.getProfile(), version.getVersion(), file); + if (this.callback == null) { + saveAs(file); + } else { + this.callback.download(version.getProfile(), version.getVersion(), file); + } + } + + public void saveAs(CurseAddon.LatestFile file) { + String extension = StringUtils.substringAfterLast(file.getFileName(), '.'); + + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle(i18n("button.save_as")); + fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(i18n("file"), "*." + extension)); + fileChooser.setInitialFileName(file.getFileName()); + File dest = fileChooser.showSaveDialog(Controllers.getStage()); + if (dest == null) { + return; + } + + Controllers.taskDialog( + new FileDownloadTask(NetworkUtils.toURL(file.getDownloadUrl()), dest).executor(true), + i18n("message.downloading") + ); } @Override @@ -194,12 +223,18 @@ public class ModDownloadPage extends Control implements DecoratorPage { listView.setCellFactory(x -> new FloatListCell(listView) { TwoLineListItem content = new TwoLineListItem(); StackPane graphicPane = new StackPane(); + JFXButton saveAsButton = new JFXButton(); { HBox container = new HBox(8); container.setAlignment(Pos.CENTER_LEFT); pane.getChildren().add(container); - container.getChildren().setAll(graphicPane, content); + + saveAsButton.getStyleClass().add("toggle-icon4"); + saveAsButton.setGraphic(SVG.contentSaveMoveOutline(Theme.blackFillBinding(), -1, -1)); + + HBox.setHgrow(content, Priority.ALWAYS); + container.getChildren().setAll(graphicPane, content, saveAsButton); } @Override @@ -208,6 +243,7 @@ public class ModDownloadPage extends Control implements DecoratorPage { content.setTitle(dataItem.getDisplayName()); content.setSubtitle(FORMATTER.format(dataItem.getParsedFileDate())); content.getTags().setAll(dataItem.getGameVersion()); + saveAsButton.setOnMouseClicked(e -> getSkinnable().saveAs(dataItem)); switch (dataItem.getReleaseType()) { case 1: // release diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java index ca6b8537f..d7ef3cb8b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java @@ -275,8 +275,8 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa AdvancedListItem worldListItem = new AdvancedListItem(); worldListItem.getStyleClass().add("navigation-drawer-item"); - worldListItem.setTitle(i18n("world")); - worldListItem.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20))); + worldListItem.setTitle(i18n("world.manage")); + worldListItem.setLeftGraphic(wrap(SVG.earth(null, 20, 20))); worldListItem.setActionButtonVisible(false); worldListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.worldListTab)); worldListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.worldListTab)); @@ -298,7 +298,7 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa new IconedMenuItem(FXUtils.limitingSize(SVG.gearOutline(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.config"), FXUtils.withJFXPopupClosing(() -> control.onBrowse("config"), browsePopup)), new IconedMenuItem(FXUtils.limitingSize(SVG.texture(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.resourcepacks"), FXUtils.withJFXPopupClosing(() -> control.onBrowse("resourcepacks"), browsePopup)), new IconedMenuItem(FXUtils.limitingSize(SVG.monitorScreenshot(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.screenshots"), FXUtils.withJFXPopupClosing(() -> control.onBrowse("screenshots"), browsePopup)), - new IconedMenuItem(FXUtils.limitingSize(SVG.gamepad(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.saves"), FXUtils.withJFXPopupClosing(() -> control.onBrowse("saves"), browsePopup)) + new IconedMenuItem(FXUtils.limitingSize(SVG.earth(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.saves"), FXUtils.withJFXPopupClosing(() -> control.onBrowse("saves"), browsePopup)) ); PopupMenu managementList = new PopupMenu(); diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index 620084c18..f4cfd8bb5 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -207,6 +207,10 @@ -fx-font-size: 12px; } +.two-line-list-item > HBox > HBox { + -fx-spacing: 8; +} + .two-line-list-item > HBox > HBox > .tag { -fx-text-fill: -fx-base-color; -fx-background-color: -fx-base-rippler-color; diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 6604a13c3..a9c7bd0f2 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -173,6 +173,44 @@ curse.category.4558=Redstone curse.category.4843=Automation curse.category.4906=MCreator +# https://addons-ecs.forgesvc.net/api/v2/category/section/6 +curse.category.399=Steampunk +curse.category.396=128x +curse.category.398=512x and Higher +curse.category.397=256x +curse.category.405=Miscellaneous +curse.category.395=64x +curse.category.400=Photo Realistic +curse.category.393=16x +curse.category.403=Traditional +curse.category.394=32x +curse.category.404=Animated +curse.category.4465=Mod Support +curse.category.402=Medieval +curse.category.401=Modern + +# https://addons-ecs.forgesvc.net/api/v2/category/section/17 +curse.category.4464=Modded World +curse.category.250=Game Map +curse.category.249=Creation +curse.category.251=Parkour +curse.category.253=Survival +curse.category.248=Adventure +curse.category.252=Puzzle + +# https://addons-ecs.forgesvc.net/api/v2/category/section/4546 +curse.category.4551=Hardcore Questing Mode +curse.category.4548=Lucky Blocks +curse.category.4556=Progression +curse.category.4752=Building Gadgets +curse.category.4553=CraftTweaker +curse.category.4554=Recipes +curse.category.4549=Guidebook +curse.category.4547=Configuration +curse.category.4550=Quests +curse.category.4555=World Gen +curse.category.4552=Scripts + curse.sort.author=Author curse.sort.date_created=Date Created curse.sort.last_updated=Last Updated @@ -206,6 +244,8 @@ fatal.config_loading_failure=The configuration is not accessible.\nPlease ensure fatal.migration_requires_manual_reboot=The update is complete. Please reopen Hello Minecraft! Launcher. fatal.apply_update_failure=We're sorry, Hello Minecraft! Launcher couldn't finish the upgrade because something went wrong.\nBut you can still manually finish the upgrade by downloading Hello Minecraft! Launcher from %s.\nPlease consider reporting this issue to us. +file=File + folder.config=Configs folder.game=Game Directory folder.mod=Mod @@ -413,7 +453,7 @@ datapack.choose_datapack=Choose the datapack zip to import datapack.extension=Datapack datapack.title=World %s - Datapacks -world=Worlds/Datapacks +world=Worlds world.add=Add world(.zip) world.datapack=Manage data packs world.datapack.1_13=Only Minecraft 1.13 and later versions support data packs. @@ -428,6 +468,7 @@ world.import.already_exists=This world already exists. world.import.choose=Choose the zip file to import world.import.failed=Unable to import this world: %s world.import.invalid=Invalid world zip file +world.manage=Worlds / Datapacks world.name=World Name world.name.enter=Enter the world name world.reveal=Reveal in Explorer diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index aa7e41bef..ea956a674 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -120,6 +120,8 @@ fatal.config_loading_failure=Hello Minecraft! Launcher 無法載入設定檔案 fatal.migration_requires_manual_reboot=Hello Minecraft! Launcher 即將升級完成,請重新開啟 Hello Minecraft! Launcher。 fatal.apply_update_failure=我們很抱歉 Hello Minecraft! Launcher 無法自動完成升級程序,因為出現了一些問題。\n但你依然可以從 %s 處手動下載 Hello Minecraft! Launcher 來完成升級。\n請考慮向我們回報該問題。 +file=檔案 + folder.config=設定資料夾 folder.game=遊戲資料夾 folder.mod=MOD 模組資料夾 @@ -313,7 +315,7 @@ datapack.choose_datapack=選擇要匯入的資料包壓縮檔 datapack.extension=資料包 datapack.title=世界 %s - 資料包 -world=世界/資料包 +world=世界 world.add=加入世界 world.datapack=管理資料包 world.datapack.1_13=僅 Minecraft 1.13 及之後的版本支援資料包 @@ -328,6 +330,7 @@ world.import.choose=選擇要匯入的存檔壓縮檔 world.import.failed=無法匯入此世界: %s world.import.invalid=無法識別的存檔壓縮包 world.game_version=遊戲版本 +world.manage=世界/資料包 world.name=世界名稱 world.name.enter=輸入世界名稱 world.reveal=開啟資料夾 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 e928ceb32..a8563bbf6 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -105,6 +105,7 @@ button.refresh=刷新 button.remove=删除 button.remove.confirm=您确定要删除吗?此操作无法撤销! button.save=保存 +button.save_as=另存为 button.yes=是 color.recent=推荐 @@ -145,7 +146,7 @@ curse.category.412=科技 curse.category.4557=红石 curse.category.428=匠魂 curse.category.414=交通运输 -curse.category.4486=Lucky Blocks +curse.category.4486=幸运方块 (Lucky Blocks) curse.category.432=建筑 (Buildcraft) curse.category.418=基因 curse.category.4671=Twitch @@ -174,6 +175,44 @@ curse.category.4558=红石 curse.category.4843=自动化 curse.category.4906=MCreator +# https://addons-ecs.forgesvc.net/api/v2/category/section/6 +curse.category.399=蒸汽朋克 +curse.category.396=128x +curse.category.398=512x 及更高 +curse.category.397=256x +curse.category.405=其他 +curse.category.395=64x +curse.category.400=仿真 +curse.category.393=16x +curse.category.403=传统 +curse.category.394=32x +curse.category.404=动态效果 +curse.category.4465=模组支持 +curse.category.402=中世纪风格 +curse.category.401=现代风格 + +# https://addons-ecs.forgesvc.net/api/v2/category/section/17 +curse.category.4464=模组 +curse.category.250=游戏挑战 +curse.category.249=创造模式 +curse.category.251=跑酷 +curse.category.253=生存模式 +curse.category.248=冒险模式 +curse.category.252=解谜类 + +# https://addons-ecs.forgesvc.net/api/v2/category/section/4546 +curse.category.4551=硬核任务模式 +curse.category.4548=幸运方块 (Lucky Blocks) +curse.category.4556=任务进度 +curse.category.4752=小物件 +curse.category.4553=CraftTweaker +curse.category.4554=合成表 +curse.category.4549=指引书 +curse.category.4547=配置 +curse.category.4550=任务 +curse.category.4555=世界生成 +curse.category.4552=脚本 + curse.sort.author=作者 curse.sort.date_created=创建日期 curse.sort.last_updated=最近更新 @@ -183,6 +222,8 @@ curse.sort.total_downloads=下载量 download=下载 download.code.404=远程服务器不包含需要下载的文件: %s +download.curseforge.customization=光影与游戏定制 +download.existing=文件已存在,无法保存。你可以选择另存为将文件保存至其他地方。 download.external_link=打开下载网站 download.failed=下载失败: %1$s,错误码:%2$d download.failed.empty=没有可供安装的版本,点击此处返回。 @@ -207,6 +248,8 @@ fatal.config_loading_failure=Hello Minecraft! Launcher 无法加载配置文件 fatal.migration_requires_manual_reboot=Hello Minecraft! Launcher 即将完成升级,请重新打开 Hello Minecraft! Launcher。 fatal.apply_update_failure=我们很抱歉 Hello Minecraft! Launcher 无法自动完成升级,因为出现了一些问题。\n但你依然可以从 %s 处手动下载 Hello Minecraft! Launcher 来完成升级。\n请考虑向我们反馈该问题。 +file=文件 + folder.config=配置文件夹 folder.game=游戏文件夹 folder.mod=MOD文件夹 @@ -415,7 +458,7 @@ datapack.choose_datapack=选择要导入的数据包压缩包 datapack.extension=数据包 datapack.title=世界 %s - 数据包 -world=世界/数据包 +world=世界 world.add=添加世界 world.datapack=管理数据包 world.datapack.1_13=仅 Minecraft 1.13 及之后的版本支持数据包 @@ -430,6 +473,7 @@ world.import.already_exists=此世界已经存在 world.import.choose=选择要导入的存档压缩包 world.import.failed=无法导入此世界:%s world.import.invalid=无法识别的存档压缩包 +world.manage=世界/数据包 world.name=世界名称 world.name.enter=输入世界名称 world.reveal=打开文件夹 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseModManager.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseModManager.java index cb0dbbf3c..c6b3b0ad4 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseModManager.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseModManager.java @@ -65,10 +65,13 @@ public final class CurseModManager { return result; } - public static final int SECTION_MODPACK = 4471; + public static final int SECTION_BUKKIT_PLUGIN = 5; public static final int SECTION_MOD = 6; + public static final int SECTION_RESOURCE_PACK = 12; + public static final int SECTION_WORLD = 17; + public static final int SECTION_MODPACK = 4471; public static final int SECTION_CUSTOMIZATION = 4546; - public static final int SECTION_ADDONS = 4559; + public static final int SECTION_ADDONS = 4559; // For Pocket Edition public static final int SECTION_UNKNOWN1 = 4944; public static final int SECTION_UNKNOWN2 = 4979; public static final int SECTION_UNKNOWN3 = 4984;