diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java index 7412424232..e4d6226028 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java @@ -356,8 +356,11 @@ public void setIconFile(Path iconFile) throws IOException { throw new IllegalArgumentException("Unsupported icon file: " + extension); } + Path dest = getInstanceRoot().resolve("icon." + extension); + if (dest.equals(iconFile)) return; + clearIconFiles(); - FileUtils.copyFile(iconFile, getInstanceRoot().resolve("icon." + extension)); + FileUtils.copyFile(iconFile, dest); invalidateIconImage(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index da8cf99b2d..92519091da 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -24,14 +24,7 @@ import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.modpack.ModAdviser; import org.jackhuang.hmcl.modpack.Modpack; -import org.jackhuang.hmcl.setting.SettingsManager; -import org.jackhuang.hmcl.setting.DefaultIsolationType; -import org.jackhuang.hmcl.setting.DownloadProviders; -import org.jackhuang.hmcl.setting.GameSettings; -import org.jackhuang.hmcl.setting.GameDirectory; -import org.jackhuang.hmcl.setting.LauncherSettings; -import org.jackhuang.hmcl.setting.LegacyGameSettingsMigrator; -import org.jackhuang.hmcl.setting.GameSettingsPresetID; +import org.jackhuang.hmcl.setting.*; import org.jackhuang.hmcl.util.FileSaver; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.StringUtils; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java index f280224498..319fe353f2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LauncherSettings.java @@ -219,6 +219,14 @@ public BooleanProperty disableAprilFoolsProperty() { return disableAprilFools; } + /// User preference for saving custom game icons. + @SerializedName("saveCustomGameIcons") + private final ObjectProperty saveCustomGameIcons = new SimpleObjectProperty<>(TriPreference.CONFIRM_EACH_TIME); + + public ObjectProperty saveCustomGameIconsProperty() { + return saveCustomGameIcons; + } + /// The common Minecraft directory selection mode. @SerializedName("commonDirectoryType") private final ObjectProperty commonDirectoryType = new RawPreservingObjectProperty<>(EnumCommonDirectory.DEFAULT); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LegacyGameSettingsMigrator.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LegacyGameSettingsMigrator.java index b322a296a4..fc35fa77a1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/LegacyGameSettingsMigrator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/LegacyGameSettingsMigrator.java @@ -72,8 +72,8 @@ private enum GameDirectoryType { CUSTOM } - /// Legacy `VersionIconType` ordinal order used by old local settings. - private static final GameInstanceIconType @Unmodifiable [] LEGACY_VERSION_ICON_TYPES = { + /// Legacy `GameInstanceIconType` ordinal order used by old local settings. + private static final GameInstanceIconType @Unmodifiable [] LEGACY_INSTANCE_ICON_TYPES = { GameInstanceIconType.DEFAULT, GameInstanceIconType.GRASS, GameInstanceIconType.CHEST, @@ -497,13 +497,13 @@ private static GameInstanceIconType parseLegacyVersionIconType(@Nullable JsonObj try { if (primitive.isNumber()) { int index = primitive.getAsInt(); - return index >= 0 && index < LEGACY_VERSION_ICON_TYPES.length - ? LEGACY_VERSION_ICON_TYPES[index] + return index >= 0 && index < LEGACY_INSTANCE_ICON_TYPES.length + ? LEGACY_INSTANCE_ICON_TYPES[index] : GameInstanceIconType.DEFAULT; } String value = primitive.getAsString(); - for (GameInstanceIconType iconType : LEGACY_VERSION_ICON_TYPES) { + for (GameInstanceIconType iconType : LEGACY_INSTANCE_ICON_TYPES) { if (iconType.name().equalsIgnoreCase(value)) { return iconType; } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/TriPreference.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/TriPreference.java new file mode 100644 index 0000000000..36179117c3 --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/TriPreference.java @@ -0,0 +1,30 @@ +/* + * 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.setting; + +public enum TriPreference { + + /// Always perform the action without asking + ALWAYS, + + /// Skip the action without asking + NEVER, + + /// Let the user decide whether to perform the action each time the event is triggered + CONFIRM_EACH_TIME +} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index 52411fb21b..09730c074c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -18,6 +18,7 @@ package org.jackhuang.hmcl.ui; import com.jfoenix.controls.JFXButton; +import com.jfoenix.controls.JFXCheckBox; import com.jfoenix.controls.JFXDialogLayout; import com.jfoenix.validation.base.ValidatorBase; import javafx.animation.KeyFrame; @@ -77,6 +78,7 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; import static org.jackhuang.hmcl.setting.SettingsManager.settings; import static org.jackhuang.hmcl.setting.SettingsManager.getAuthlibInjectorServers; @@ -514,6 +516,24 @@ public static void dialogLater(Region content) { decorator.showDialogLater(content); } + public static void askTriPreference(String text, @Nullable Consumer resConsumer, @Nullable Consumer prefConsumer) { + var r = Objects.requireNonNullElse(resConsumer, (__) -> {}); + var p = Objects.requireNonNullElse(prefConsumer, (__) -> {}); + + var check = new JFXCheckBox(i18n("button.do_not_show_again")); + var dialog = new MessageDialogPane.Builder(text, i18n("message.question"), MessageDialogPane.MessageType.QUESTION) + .addActionNoClosing(check) + .yesOrNo(() -> { + r.accept(true); + p.accept(check.isSelected() ? TriPreference.ALWAYS : TriPreference.CONFIRM_EACH_TIME); + }, () -> { + r.accept(false); + p.accept(check.isSelected() ? TriPreference.NEVER : TriPreference.CONFIRM_EACH_TIME); + }) + .build(); + dialog(dialog); + } + public static CompletableFuture prompt(String title, FutureCallback onResult) { return prompt(title, onResult, ""); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ImageContainer.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ImageContainer.java index c9aa50c8c0..f8c0d49d42 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ImageContainer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ImageContainer.java @@ -64,6 +64,11 @@ public ImageContainer(double width, double height) { this.getChildren().setAll(imageView); } + public ImageContainer(double size, Image image) { + this(size); + setImage(image); + } + private void updateCornerRadius(double radius) { clip.setArcWidth(radius); clip.setArcHeight(radius); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java index 2bed442a5f..7e5b7c7f0f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java @@ -169,6 +169,11 @@ public Builder addAction(String text, @Nullable Runnable action) { return this; } + public Builder addActionNoClosing(Node actionNode) { + dialog.actions.getChildren().add(actionNode); + return this; + } + public Builder ok(@Nullable Runnable ok) { JFXButton btnOk = new JFXButton(i18n("button.ok")); btnOk.getStyleClass().add("dialog-accept"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameInstanceIconDialog.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameInstanceIconDialog.java index 944a85aa00..9b2421eb84 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameInstanceIconDialog.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameInstanceIconDialog.java @@ -24,24 +24,38 @@ import javafx.scene.image.ImageView; import javafx.scene.layout.FlowPane; import javafx.stage.FileChooser; +import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.game.HMCLGameInstance; import org.jackhuang.hmcl.setting.GameSettings; import org.jackhuang.hmcl.setting.GameInstanceIconType; +import org.jackhuang.hmcl.setting.SettingsManager; +import org.jackhuang.hmcl.setting.TriPreference; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.construct.DialogCloseEvent; +import org.jackhuang.hmcl.ui.construct.ImageContainer; import org.jackhuang.hmcl.ui.construct.RipplerContainer; +import org.jackhuang.hmcl.util.io.FileUtils; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Objects; import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed; import static org.jackhuang.hmcl.util.logging.Logger.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public class GameInstanceIconDialog extends JFXDialogLayout { + + public static final Path INSTANCE_ICONS_DIR = Metadata.HMCL_LOCAL_HOME.resolve("instance_icons"); + + private static final SimpleDateFormat fileNameFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss_"); private final HMCLGameInstance gameInstance; private final Runnable onFinish; private final GameSettings.@Nullable Instance setting; @@ -71,6 +85,18 @@ public GameInstanceIconDialog(HMCLGameInstance gameInstance, Runnable onFinish) createIcon(GameInstanceIconType.FURNACE), createIcon(GameInstanceIconType.QUILT) ); + if (Files.isDirectory(INSTANCE_ICONS_DIR)) { + try (var stream = Files.list(INSTANCE_ICONS_DIR)) { + pane.getChildren().addAll( + stream.filter(p -> Files.isRegularFile(p) && FXUtils.IMAGE_EXTENSIONS.contains(FileUtils.getExtension(p).toLowerCase(Locale.ROOT))) + .map(this::createIcon) + .filter(Objects::nonNull) + .toList() + ); + } catch (Exception e) { + LOG.warning("Failed to load custom instance icons at " + INSTANCE_ICONS_DIR, e); + } + } setBody(pane); JFXButton cancelButton = new JFXButton(i18n("button.cancel")); @@ -86,17 +112,52 @@ private void exploreIcon() { chooser.getExtensionFilters().add(FXUtils.getImageExtensionFilter()); Path selectedFile = Controllers.showOpenDialog(chooser); if (selectedFile != null) { - try { - gameInstance.setIconFile(selectedFile); + TriPreference pref = SettingsManager.settings().saveCustomGameIconsProperty().get(); + if (pref == TriPreference.CONFIRM_EACH_TIME && !INSTANCE_ICONS_DIR.equals(selectedFile.getParent())) { + Controllers.askTriPreference( + i18n("settings.icon.save"), + (b) -> setCustomIcon(selectedFile, b), + (p) -> SettingsManager.settings().saveCustomGameIconsProperty().set(p) + ); + } else { + setCustomIcon(selectedFile, pref == TriPreference.ALWAYS); + } + } + } - if (setting != null) { - setting.iconProperty().setValue(GameInstanceIconType.DEFAULT); - } + private Path saveIcon(Path selectedFile) throws IOException { + String date = fileNameFormat.format(new Date()); + Path dest = INSTANCE_ICONS_DIR.resolve(date + selectedFile.getFileName()); + { + int i = 1; + String nameBase = date + FileUtils.getNameWithoutExtension(selectedFile); + String ext = FileUtils.getExtension(selectedFile); + while (Files.exists(dest)) { + dest = INSTANCE_ICONS_DIR.resolve(nameBase + "_" + i + "." + ext); + i++; + } + } + FileUtils.copyFile(selectedFile, dest); + return dest; + } - onAccept(); - } catch (IOException | IllegalArgumentException e) { - LOG.error("Failed to set icon file: " + selectedFile, e); + private void setCustomIcon(Path selectedFile, boolean save) { + try { + Path dest; + if (INSTANCE_ICONS_DIR.equals(selectedFile.getParent()) || !save) { + dest = selectedFile; + } else { + dest = saveIcon(selectedFile); + } + gameInstance.setIconFile(dest); + + if (setting != null) { + setting.iconProperty().setValue(GameInstanceIconType.DEFAULT); } + + onAccept(); + } catch (IOException | IllegalArgumentException e) { + LOG.error("Failed to set instance icon file: " + selectedFile, e); } } @@ -125,6 +186,32 @@ private Node createIcon(GameInstanceIconType type) { return container; } + private Node createIcon(Path path) { + ImageContainer imageContainer; + try { + imageContainer = new ImageContainer(32, FXUtils.loadImage(path, 64, 64, true, true)); + } catch (Exception e) { + LOG.warning("Failed to load custom instance icon at " + path, e); + return null; + } + imageContainer.setMouseTransparent(true); + RipplerContainer container = new RipplerContainer(imageContainer); + FXUtils.setLimitWidth(container, 36); + FXUtils.setLimitHeight(container, 36); + FXUtils.onClicked(container, () -> { + try { + gameInstance.setIconFile(path); + if (setting != null) { + setting.iconProperty().setValue(GameInstanceIconType.DEFAULT); + onAccept(); + } + } catch (IOException e) { + LOG.error("Failed to set icon file: " + path, e); + } + }); + return container; + } + protected void onAccept() { // Icon file / settings.iconProperty updates already invalidate iconImageProperty. onFinish.run(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java index 7745691953..ab7c85b78e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java @@ -31,6 +31,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import org.jackhuang.hmcl.Metadata; +import org.jackhuang.hmcl.setting.TriPreference; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; @@ -208,6 +209,20 @@ else if (locale.isSameLanguage(currentLocale)) miscPaneList.getContent().add(disableAprilFools); } + { + LineSelectButton saveCustomGameIconsPane = new LineSelectButton<>(); + saveCustomGameIconsPane.setTitle(i18n("settings.launcher.save_custom_game_icons")); + saveCustomGameIconsPane.valueProperty().bindBidirectional(settings().saveCustomGameIconsProperty()); + saveCustomGameIconsPane.setConverter(a -> switch (a) { + case CONFIRM_EACH_TIME -> i18n("message.tri_pref.confirm_each_time"); + case ALWAYS -> i18n("message.tri_pref.always"); + case NEVER -> i18n("message.tri_pref.never"); + }); + saveCustomGameIconsPane.setItems(TriPreference.values()); + + miscPaneList.getContent().add(saveCustomGameIconsPane); + } + { BorderPane debugPane = new BorderPane(); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 4e4a249359..88e1eab4a4 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -986,6 +986,9 @@ message.success=Operation successfully completed message.unknown=Unknown message.warning=Warning message.question=Question +message.tri_pref.always=Always +message.tri_pref.never=Never +message.tri_pref.confirm_each_time=Confirm Each Time modpack=Modpacks modpack.choose=Choose Modpack @@ -1531,6 +1534,7 @@ settings.game.window_type.windowed=Windowed settings.game.working_directory.choose=Choose the working directory settings.icon=Icon +settings.icon.save=Save custom instance icon? settings.game_directories.read_only=The game directory file was saved by a newer version of HMCL. The current version of HMCL cannot modify game directories. settings.launcher=Launcher Settings @@ -1577,6 +1581,7 @@ settings.launcher.proxy.password=Password settings.launcher.proxy.port=Port settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=Username +settings.launcher.save_custom_game_icons=Save Custom Game Icons settings.launcher.theme=Theme settings.launcher.theme_color=Theme Color settings.launcher.theme_color_style=Color Style diff --git a/HMCL/src/main/resources/assets/lang/I18N_ar.properties b/HMCL/src/main/resources/assets/lang/I18N_ar.properties index 5111f7490b..9fc003f62f 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ar.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ar.properties @@ -987,6 +987,9 @@ message.success=اكتملت العملية بنجاح message.unknown=غير معروف message.warning=تحذير message.question=سؤال +# message.tri_pref.always= +# message.tri_pref.never= +# message.tri_pref.confirm_each_time= modpack=حزم المودات modpack.choose=اختر حزمة مودات @@ -1529,6 +1532,7 @@ settings.game.management=إدارة settings.game.working_directory.choose=اختر مجلد العمل settings.icon=الأيقونة +# settings.icon.save= # settings.game_directories.read_only= settings.launcher=إعدادات المشغّل @@ -1575,6 +1579,7 @@ settings.launcher.proxy.password=كلمة المرور settings.launcher.proxy.port=المنفذ settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=اسم المستخدم +# settings.launcher.save_custom_game_icons= settings.launcher.theme=لون السمة # settings.launcher.theme_color= # settings.launcher.theme_color_style= diff --git a/HMCL/src/main/resources/assets/lang/I18N_de.properties b/HMCL/src/main/resources/assets/lang/I18N_de.properties index 6d474be5f7..71fea4265b 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_de.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_de.properties @@ -986,6 +986,9 @@ message.success=Vorgang erfolgreich abgeschlossen message.unknown=Unbekannt message.warning=Warnung message.question=Frage +# message.tri_pref.always= +# message.tri_pref.never= +# message.tri_pref.confirm_each_time= modpack=Modpacks modpack.choose=Modpack auswählen @@ -1530,6 +1533,7 @@ settings.game.window_type.windowed=Im Fenster settings.game.working_directory.choose=Wählen Sie das Arbeitsverzeichnis settings.icon=Symbol +# settings.icon.save= settings.game_directories.read_only=Die Spielverzeichnisdatei wurde von einer neueren Version des HMCL gespeichert. Die aktuelle Version des HMCL kann keine Spielverzeichnisse ändern. settings.launcher=Launcher-Einstellungen @@ -1576,6 +1580,7 @@ settings.launcher.proxy.password=Passwort settings.launcher.proxy.port=Port settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=Benutzername +# settings.launcher.save_custom_game_icons= settings.launcher.theme=Design settings.launcher.theme_color=Designfarbe settings.launcher.theme_color_style=Farbstil diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index d61b585a42..b7b081b05a 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -979,6 +979,9 @@ message.success=Operación completada con éxito message.unknown=Desconocido message.warning=Atención # message.question= +# message.tri_pref.always= +# message.tri_pref.never= +# message.tri_pref.confirm_each_time= modpack=Modpacks modpack.choose=Elija Modpack @@ -1521,6 +1524,7 @@ settings.game.management=Gestionar settings.game.working_directory.choose=Elija el directorio de trabajo settings.icon=Icono +# settings.icon.save= # settings.game_directories.read_only= settings.launcher=Configuración del launcher @@ -1567,6 +1571,7 @@ settings.launcher.proxy.password=Contraseña settings.launcher.proxy.port=Puerto settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=Nombre de usuario +# settings.launcher.save_custom_game_icons= settings.launcher.theme=Tema # settings.launcher.theme_color= # settings.launcher.theme_color_style= diff --git a/HMCL/src/main/resources/assets/lang/I18N_ja.properties b/HMCL/src/main/resources/assets/lang/I18N_ja.properties index 323189a2bd..3f71456f7b 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ja.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ja.properties @@ -789,6 +789,9 @@ message.success=ジョブは正常に完了しました message.unknown=不明 message.warning=警告 # message.question= +# message.tri_pref.always= +# message.tri_pref.never= +# message.tri_pref.confirm_each_time= modpack=Modpack modpack.choose=modpackを選択(zip)。 @@ -1325,6 +1328,7 @@ settings.game.management=管理 settings.game.working_directory.choose=作業ディレクトリを選択してください settings.icon=ゲームアイコン +# settings.icon.save= # settings.game_directories.read_only= settings.launcher=設定 @@ -1371,6 +1375,7 @@ settings.launcher.proxy.password=パスワード settings.launcher.proxy.port=ポート settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=アカウント +# settings.launcher.save_custom_game_icons= settings.launcher.theme=テーマ # settings.launcher.theme_color= # settings.launcher.theme_color_style= diff --git a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties index 5d23c25050..16bd65cf21 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties @@ -801,6 +801,9 @@ message.success=畢 message.unknown=未明 message.warning=誡 # message.question= +# message.tri_pref.always= +# message.tri_pref.never= +# message.tri_pref.confirm_each_time= modpack=改囊集 modpack.choose=擇一欲裝之改囊集案 @@ -1337,6 +1340,7 @@ settings.game.management=司 settings.game.working_directory.choose=擇戯運之處 settings.icon=戲徵 +# settings.icon.save= # settings.game_directories.read_only= settings.launcher=啟者置設 @@ -1383,6 +1387,7 @@ settings.launcher.proxy.password=符節 settings.launcher.proxy.port=端口 settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=戶簿 +# settings.launcher.save_custom_game_icons= settings.launcher.theme=主題 # settings.launcher.theme_color= # settings.launcher.theme_color_style= diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 0474f4e690..9f8756f2f0 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -974,6 +974,9 @@ message.success=Операция успешно завершена message.unknown=Неизвестно message.warning=Предупреждение # message.question= +# message.tri_pref.always= +# message.tri_pref.never= +# message.tri_pref.confirm_each_time= modpack=Модпаки modpack.choose=Выберите модпак @@ -1517,6 +1520,7 @@ settings.game.management=Инструменты settings.game.working_directory.choose=Выберите рабочую папку settings.icon=Значок +# settings.icon.save= # settings.game_directories.read_only= settings.launcher=Настройки лаунчера @@ -1563,6 +1567,7 @@ settings.launcher.proxy.password=Пароль settings.launcher.proxy.port=Порт settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=Имя пользователя +# settings.launcher.save_custom_game_icons= settings.launcher.theme=Тема # settings.launcher.theme_color= # settings.launcher.theme_color_style= diff --git a/HMCL/src/main/resources/assets/lang/I18N_uk.properties b/HMCL/src/main/resources/assets/lang/I18N_uk.properties index 4afbf45756..558bfefef0 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_uk.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_uk.properties @@ -941,6 +941,9 @@ message.success=Операція успішно завершена message.unknown=Невідомо message.warning=Попередження message.question=Питання +# message.tri_pref.always= +# message.tri_pref.never= +# message.tri_pref.confirm_each_time= modpack=Модпаки modpack.choose=Вибрати модпак @@ -1484,6 +1487,7 @@ settings.game.window_type.windowed=Віконне settings.game.working_directory.choose=Вибрати робочий каталог settings.icon=Іконка +# settings.icon.save= settings.game_directories.read_only=Файл директорії гри був збережений новішою версією HMCL. Поточна версія HMCL не може змінювати директорії гри. settings.launcher=Налаштування лаунчера @@ -1530,6 +1534,7 @@ settings.launcher.proxy.password=Пароль settings.launcher.proxy.port=Порт settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=Ім'я користувача +# settings.launcher.save_custom_game_icons= settings.launcher.theme=Тема settings.launcher.theme_color=Колір теми settings.launcher.theme_color_style=Стиль кольору diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties index 797ed0852b..9dbdf1d3ff 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_Hans.properties @@ -804,6 +804,9 @@ message.success=完成 message.unknown=未知 message.warning=警告 message.question=确认 +message.tri_pref.always=总是 +message.tri_pref.never=从不 +message.tri_pref.confirm_each_time=每次询问 modpack=整合包 modpack.choose=选择要安装的游戏整合包文件 @@ -1343,6 +1346,7 @@ settings.game.window_type.windowed=窗口化 settings.game.working_directory.choose=选择运行文件夹 settings.icon=游戏图标 +settings.icon.save=是否保存自定义实例图标? settings.game_directories.read_only=游戏文件夹配置文件是由更高版本的 HMCL 保存的,当前版本的 HMCL 无法修改游戏文件夹。 settings.launcher=启动器设置 @@ -1389,6 +1393,7 @@ settings.launcher.proxy.password=密码 settings.launcher.proxy.port=端口 settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=账户 +settings.launcher.save_custom_game_icons=保存自定义游戏图标 settings.launcher.theme=主题 settings.launcher.theme_color=主题色 settings.launcher.theme_color_style=色彩模式 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties index 3c3f352714..6ab8ac49aa 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_Hant.properties @@ -798,6 +798,9 @@ message.success=完成 message.unknown=未知 message.warning=警告 message.question=確認 +message.tri_pref.always=總是 +message.tri_pref.never=從不 +message.tri_pref.confirm_each_time=每次詢問 modpack=模組包 modpack.choose=選取要安裝的遊戲模組包檔案 @@ -1337,6 +1340,7 @@ settings.game.window_type.windowed=視窗化 settings.game.working_directory.choose=選取執行目錄 settings.icon=遊戲圖示 +settings.icon.save=是否儲存自定義例項圖示? settings.game_directories.read_only=遊戲目錄設定檔是由更高版本的 HMCL 儲存的,目前版本的 HMCL 無法新增遊戲目錄。 settings.launcher=啟動器設定 @@ -1383,6 +1387,7 @@ settings.launcher.proxy.password=密碼 settings.launcher.proxy.port=連線埠 settings.launcher.proxy.socks=SOCKS settings.launcher.proxy.username=帳戶 +settings.launcher.save_custom_game_icons=保存自定義遊戲圖示 settings.launcher.theme=主題色 settings.launcher.theme_color=主題色 settings.launcher.theme_color_style=色彩模式