Compare commits

...
Author SHA1 Message Date
3gf8jv4dv d5ec6d7b85 Revise i18n translation before releases (#3428)
- Fix some English grammar and text style
- Revise `Allow Cheats` to `Allow Commands/Cheats`
  - Due to the change from `Allow Cheats` to `Allow Commands` by Mojang in 24w04a.
  - https://minecraft.wiki/w/Java_Edition_24w04a
2024-11-07 21:37:59 +08:00
Glavo 13856b71a0 更新 HMCLauncher.exe (#3427) 2024-11-05 03:43:18 +08:00
Glavo c6658771ca 修复 HMCLauncher 无法正常识别 Windows on Arm 平台的问题 (#3425)
* update

* update

* update
2024-11-05 00:20:42 +08:00
Glavo 406f36584d 设置 FontComboBox 的最小宽度 (#3424) 2024-11-04 18:55:04 +08:00
Glavo 898750d058 修复对话框按钮自行移动的问题 (#3423)
* 修复对话框按钮自行移动的问题

* update

* update

* update
2024-11-04 18:41:14 +08:00
Glavo 09e9e934d3 Fix #3412: 修复点击前置模组时,模组下载对话框不会关闭的问题 (#3422) 2024-11-04 06:00:45 +08:00
Glavo 3d170267b7 Fix #3416: 修复打开游戏设置页时崩溃的问题 (#3421) 2024-11-04 05:34:28 +08:00
3gf8jv4dv 3ca7e3cf88 Fix incorrect i18n key and line breaks in es & ja (#3404)
* Fix incorrect i18n key and line breaks in es & ja

* fix
2024-11-03 17:03:41 +08:00
3gf8jv4dv 1378d1445a README & PLATFORM docs post-fixes (#3417) 2024-11-02 17:36:41 +08:00
3gf8jv4dv 16d304dbb4 en_US Post-fix (#3413)
* en_US Post-fix

Some minor fixes.

* fix `game.crash.feedback`

* oops...

* oops...

* Bunch of grammar fixes :/

* Another bunch fixes

* Minor fixes

* fix

* fix

* fix
2024-11-02 17:36:20 +08:00
3gf8jv4dv aff5db7759 Change the terminology %AppData% to %APPDATA% (#3420) 2024-11-02 02:27:54 +08:00
Glavo 0697aa9755 重命名包 moe.mickey.minecraft.skin.fx (#3419) 2024-11-02 01:05:52 +08:00
Glavo 995d3bd4b9 不再生成 bss 文件 (#3418) 2024-11-01 20:59:33 +08:00
Glavo 3bf5204e79 优化 Theme (#3414) 2024-11-01 02:12:16 +08:00
3gf8jv4dv 0b1ce6e94a Adjust language selection order (#3411)
Sort alphabetically by language code.
2024-10-31 23:30:44 +08:00
3gf8jv4dv a66ccd7385 Adjust Microsoft login related i18n (#3393)
* Adjust Microsoft login related i18n

- Adjust English and Chinese
- Fix typos and grammatical errors

* fix
2024-10-30 02:26:55 +08:00
3gf8jv4dv 7a3f125802 Adjust custom command hint (zh_CN only) (#3394)
I forgot to change the zh_CN part.
A half-width colon is better.
2024-10-30 02:22:34 +08:00
3gf8jv4dv 4a8dcce3d4 Adjust about page i18n (#3398)
* Adjust about page i18n

- Adjust all languages
- Add missing translations

* fix

* fix
2024-10-30 02:21:54 +08:00
3gf8jv4dv adcc3eb43f Adjust buttons, chat & crash i18n (#3401)
* Adjust buttons, chat & crash i18n

- Add missing translations

* fix

* fix

* fix

* fix ja

* fix es & ja
2024-10-30 02:20:39 +08:00
3gf8jv4dv 8bbd1a7cf4 Remove unused i18n keys in es, ja & ru (#3405) 2024-10-30 02:19:45 +08:00
Zkitefly 467ff26278 模组管理添加右键查看模组详情 (#3232)
* Update ModListPageSkin.java

* Update ModListPageSkin.java

* Update ModListPageSkin.java

* Update ModListPageSkin.java

* Update ModListPageSkin.java
2024-10-30 02:19:16 +08:00
Glavo d6a267afa4 优化 FXUtils.installTooltip (#3407)
* update

* Fix checkstyle

* update

* update

* update

* update

* update
2024-10-28 01:52:38 +08:00
Glavo 743e934436 优化“复制”图标 (#3406) 2024-10-28 00:29:29 +08:00
3gf8jv4dv f89ac2231a Adjust Java management i18n (#3402)
- Add missing languages.
2024-10-27 22:07:25 +08:00
3gf8jv4dv 1877a18ebb Fix en language missing a line break (#3403) 2024-10-27 22:07:03 +08:00
Glavo c99f85d9d5 缩小复制图标 (#3397)
* update

* update
2024-10-27 00:21:31 +08:00
Glavo 228942c60a 优化删除账号按钮图标 (#3396) 2024-10-26 23:49:43 +08:00
Glavo fecd567eab 简化 ContainerAnimations (#3395) 2024-10-26 23:34:41 +08:00
3gf8jv4dv 602840519b Change forgot password link (#3392) 2024-10-26 23:32:12 +08:00
959adf1075 更改主页 UI (#3129)
* Change root page UI

* Update HMCL/src/main/resources/assets/lang/I18N.properties

Co-authored-by: 3gf8jv4dv <158490944+3gf8jv4dv@users.noreply.github.com>

* Shorten I18N

* update

---------

Co-authored-by: 3gf8jv4dv <158490944+3gf8jv4dv@users.noreply.github.com>
Co-authored-by: Glavo <zjx001202@gmail.com>
2024-10-26 21:02:34 +08:00
Glavo 422f681fe6 Bump XZ to 1.10 (#3391) 2024-10-26 20:54:48 +08:00
Glavo 474d298fd3 Bump Gradle to 8.10.2 (#3390) 2024-10-26 13:52:49 +08:00
3gf8jv4dv 4052136217 Adjust sponsor hint i18n (#3387)
- Adjust for all languages.
- For BMCLAPI: Make it clear that this is a service
  for users in Chinese Mainland.
- For HMCL: Since the page that was opened was not
  Afdian but the GitHub repo page, I made adjustments
  based on the actual situation.
- Fix some typos.
2024-10-26 02:51:19 +08:00
3gf8jv4dv 3193e02867 Adjust feedback page i18n (#3389)
- Adjust for all languages.
- Add missing translations to some languages.
2024-10-26 02:49:58 +08:00
Glavo c7122b3fff 优化首页公告 (#3378)
* update

* 添加公告隐藏动画

* update

* update
2024-10-26 02:45:58 +08:00
3gf8jv4dv 8775194d26 Adjust i18n for Linux/FreeBSD-specific settings in Advanced Settings (#3388)
I checked the code and it looked like this was a
Linux/FreeBSD-specific feature, so I adjusted the
translation for that.
2024-10-26 01:14:28 +08:00
3gf8jv4dv b3f27cc96e Adjust homepage hint typesetting (#3382)
- Adjustments made for all languages.
- Remove outdated hidden hint links.
2024-10-25 22:30:12 +08:00
3gf8jv4dv 3313a1ed27 For language selection, remove all region descriptions (#3383)
Currently, HMCL does not provide variants for
languages ​​(e.g. US, UK, etc.). For Chinese, there
are already descriptions of Simplified (简体) and
Traditional (繁體) to distinguish them, so keep them.
2024-10-25 22:05:19 +08:00
3gf8jv4dv da66622994 Adjust Microsoft login hint (zh_CN only) (#3384) 2024-10-25 22:04:48 +08:00
3gf8jv4dv 446cdc32d7 Adjust language file header comments (#3385)
- Update copyright year
- Unify typesetting style
2024-10-25 22:03:52 +08:00
3gf8jv4dv b08d2b0dc0 Remove some unnecessary tooltips (#3386)
* Remove some unnecessary tooltips

These texts are basically fixed, and the problem of
too long texts can be solved by revising the translation
for different languages.

Currently, for both Chinese and English, the i18n
keys involved in this PR will not be partially obscured
due to long text, so their tooltips are removed.

* fix checkstyle
2024-10-25 16:11:16 +08:00
Glavo e051c212d1 支持使用鼠标返回键返回上级 (#3381)
* 支持使用鼠标返回键返回上级

* fix checkstyle
2024-10-25 12:36:07 +08:00
Glavo 7645a600ef 修复部分控件响应任意鼠标按键点击事件的问题 (#3380)
* update

* update

* update

* update

* update

* update

* update

* update

* update
2024-10-25 12:24:57 +08:00
Glavo 9e56b5cd15 清理对 setOnMouseClicked 的误用 (#3379) 2024-10-25 04:08:40 +08:00
94 changed files with 1298 additions and 1226 deletions

No files matched your search

-18
View File
@@ -167,24 +167,6 @@ fun createExecutable(suffix: String, header: String) {
}
tasks.processResources {
fun convertToBSS(resource: String) {
doFirst {
val cssFile = File(projectDir, "src/main/resources/$resource")
val bssFile = File(projectDir, "build/compiled-resources/${resource.substring(0, resource.length - 4)}.bss")
bssFile.parentFile.mkdirs()
javaexec {
classpath = sourceSets["main"].compileClasspath
mainClass.set("com.sun.javafx.css.parser.Css2Bin")
args(cssFile, bssFile)
}
}
}
from("build/compiled-resources")
convertToBSS("assets/css/root.css")
convertToBSS("assets/css/blue.css")
into("META-INF/versions/11") {
from(sourceSets["java11"].output)
}
@@ -24,9 +24,8 @@ import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.IOUtils;
import java.io.File;
import java.io.IOException;
@@ -36,11 +35,10 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
@@ -58,34 +56,6 @@ public class Theme {
Color.web("#B71C1C") // red
};
private static Charset cssCharset;
private static Charset getCssCharset() {
if (cssCharset != null)
return cssCharset;
Charset defaultCharset = Charset.defaultCharset();
if (defaultCharset != StandardCharsets.UTF_8) {
// https://bugs.openjdk.org/browse/JDK-8279328
// For JavaFX 17 or earlier, native encoding should be used
String jfxVersion = System.getProperty("javafx.version");
if (jfxVersion != null) {
Matcher matcher = Pattern.compile("^(?<version>[0-9]+)").matcher(jfxVersion);
if (matcher.find()) {
int v = Lang.parseInt(matcher.group(), -1);
if (v >= 18) {
cssCharset = StandardCharsets.UTF_8;
}
}
}
}
if (cssCharset == null)
cssCharset = defaultCharset;
return cssCharset;
}
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private static Optional<Font> font;
@@ -145,6 +115,14 @@ public class Theme {
return isLight() ? Color.BLACK : Color.WHITE;
}
private static String rgba(Color color, double opacity) {
return String.format("rgba(%d, %d, %d, %.1f)",
(int) Math.ceil(color.getRed() * 256),
(int) Math.ceil(color.getGreen() * 256),
(int) Math.ceil(color.getBlue() * 256),
opacity);
}
public String[] getStylesheets(String overrideFontFamily) {
String css = "/assets/css/blue.css";
@@ -163,30 +141,44 @@ public class Theme {
if (fontFamily != null || !this.color.equalsIgnoreCase(BLUE.color)) {
Color textFill = getForegroundColor();
String fontCss = "";
if (fontFamily != null) {
fontCss = "-fx-font-family: \"" + fontFamily + "\";";
if (fontStyle != null && !fontStyle.isEmpty())
fontCss += " -fx-font-style: \"" + fontStyle + "\";";
}
try {
File temp = File.createTempFile("hmcl", ".css");
String themeText = IOUtils.readFullyAsString(Theme.class.getResourceAsStream("/assets/css/custom.css"))
.replace("%base-color%", color)
.replace("%base-red%", Integer.toString((int) Math.ceil(paint.getRed() * 256)))
.replace("%base-green%", Integer.toString((int) Math.ceil(paint.getGreen() * 256)))
.replace("%base-blue%", Integer.toString((int) Math.ceil(paint.getBlue() * 256)))
.replace("%base-rippler-color%", String.format("rgba(%d, %d, %d, 0.3)", (int) Math.ceil(paint.getRed() * 256), (int) Math.ceil(paint.getGreen() * 256), (int) Math.ceil(paint.getBlue() * 256)))
.replace("%disabled-font-color%", String.format("rgba(%d, %d, %d, 0.7)", (int) Math.ceil(textFill.getRed() * 256), (int) Math.ceil(textFill.getGreen() * 256), (int) Math.ceil(textFill.getBlue() * 256)))
.replace("%font-color%", getColorDisplayName(getForegroundColor()))
.replace("%font%", fontCss);
FileUtils.writeText(temp, themeText, getCssCharset());
temp.deleteOnExit();
css = temp.toURI().toString();
} catch (IOException | NullPointerException e) {
LOG.error("Unable to create theme stylesheet. Fallback to blue theme.", e);
}
StringBuilder themeBuilder = new StringBuilder(512);
themeBuilder.append(".root {")
.append("-fx-base-color:").append(color).append(';')
.append("-fx-base-darker-color: derive(-fx-base-color, -10%);")
.append("-fx-base-check-color: derive(-fx-base-color, 30%);")
.append("-fx-rippler-color:").append(rgba(paint, 0.3)).append(';')
.append("-fx-base-rippler-color: derive(").append(rgba(paint, 0.3)).append(", 100%);")
.append("-fx-base-disabled-text-fill:").append(rgba(textFill, 0.7)).append(";")
.append("-fx-base-text-fill:").append(getColorDisplayName(getForegroundColor())).append(";")
.append("-theme-thumb:").append(rgba(paint, 0.7)).append(";");
if (fontFamily == null)
// https://github.com/HMCL-dev/HMCL/pull/3423
themeBuilder.append("-fx-font-family: -fx-base-font-family;");
else
themeBuilder.append("-fx-font-family:\"").append(fontFamily).append("\";");
if (fontStyle != null && !fontStyle.isEmpty())
themeBuilder.append("-fx-font-style:\"").append(fontStyle).append("\";");
themeBuilder.append('}');
if (FXUtils.JAVAFX_MAJOR_VERSION >= 17)
// JavaFX 17+ support loading stylesheets from data URIs
// https://bugs.openjdk.org/browse/JDK-8267554
css = "data:text/css;charset=UTF-8;base64," + Base64.getEncoder().encodeToString(themeBuilder.toString().getBytes(StandardCharsets.UTF_8));
else
try {
File temp = File.createTempFile("hmcl", ".css");
// For JavaFX 17 or earlier, CssParser uses the default charset
// https://bugs.openjdk.org/browse/JDK-8279328
FileUtils.writeText(temp, themeBuilder.toString(), Charset.defaultCharset());
temp.deleteOnExit();
css = temp.toURI().toString();
} catch (IOException | NullPointerException e) {
LOG.error("Unable to create theme stylesheet. Fallback to blue theme.", e);
}
}
return new String[]{css, "/assets/css/root.css"};
@@ -235,7 +227,7 @@ public class Theme {
}
public static String getColorDisplayName(Color c) {
return c != null ? String.format("#%02x%02x%02x", Math.round(c.getRed() * 255.0D), Math.round(c.getGreen() * 255.0D), Math.round(c.getBlue() * 255.0D)).toUpperCase(Locale.ROOT) : null;
return c != null ? String.format("#%02X%02X%02X", Math.round(c.getRed() * 255.0D), Math.round(c.getGreen() * 255.0D), Math.round(c.getBlue() * 255.0D)) : null;
}
private static ObjectBinding<Color> FOREGROUND_FILL;
@@ -391,9 +391,6 @@ public final class Controllers {
Controllers.getSettingsPage().showFeedback();
Controllers.navigate(Controllers.getSettingsPage());
break;
case "hmcl://hide-announcement":
Controllers.getRootPage().getMainPage().hideAnnouncementPane();
break;
}
} else {
FXUtils.openLink(href);
@@ -53,7 +53,7 @@ public class CrashWindow extends Stage {
Button btnContact = new Button();
btnContact.setText(i18n("launcher.contact"));
btnContact.setOnMouseClicked(event -> FXUtils.openLink(Metadata.CONTACT_URL));
btnContact.setOnAction(event -> FXUtils.openLink(Metadata.CONTACT_URL));
HBox box = new HBox();
box.setStyle("-fx-padding: 8px;");
box.getChildren().add(btnContact);
@@ -54,6 +54,7 @@ import org.glavo.png.javafx.PNGJavaFXUtils;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
import org.jackhuang.hmcl.util.Holder;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.ResourceNotFoundError;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
@@ -72,8 +73,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
@@ -85,6 +84,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.Lang.thread;
@@ -96,6 +97,20 @@ public final class FXUtils {
private FXUtils() {
}
public static final int JAVAFX_MAJOR_VERSION;
static {
String jfxVersion = System.getProperty("javafx.version");
int majorVersion = -1;
if (jfxVersion != null) {
Matcher matcher = Pattern.compile("^(?<version>[0-9]+)").matcher(jfxVersion);
if (matcher.find()) {
majorVersion = Lang.parseInt(matcher.group(), -1);
}
}
JAVAFX_MAJOR_VERSION = majorVersion;
}
public static final String DEFAULT_MONOSPACE_FONT = OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "Consolas" : "Monospace";
private static final Map<String, Image> builtinImageCache = new ConcurrentHashMap<>();
@@ -298,8 +313,12 @@ public final class FXUtils {
ScrollUtils.addSmoothScrolling(scrollPane);
}
private static final Duration TOOLTIP_FAST_SHOW_DELAY = Duration.millis(50);
private static final Duration TOOLTIP_SLOW_SHOW_DELAY = Duration.millis(500);
private static final Duration TOOLTIP_SHOW_DURATION = Duration.millis(5000);
public static void installFastTooltip(Node node, Tooltip tooltip) {
installTooltip(node, 50, 5000, 0, tooltip);
runInFX(() -> TooltipInstaller.INSTALLER.installTooltip(node, TOOLTIP_FAST_SHOW_DELAY, TOOLTIP_SHOW_DURATION, Duration.ZERO, tooltip));
}
public static void installFastTooltip(Node node, String tooltip) {
@@ -307,39 +326,13 @@ public final class FXUtils {
}
public static void installSlowTooltip(Node node, Tooltip tooltip) {
installTooltip(node, 500, 5000, 0, tooltip);
runInFX(() -> TooltipInstaller.INSTALLER.installTooltip(node, TOOLTIP_SLOW_SHOW_DELAY, TOOLTIP_SHOW_DURATION, Duration.ZERO, tooltip));
}
public static void installSlowTooltip(Node node, String tooltip) {
installSlowTooltip(node, new Tooltip(tooltip));
}
public static void installTooltip(Node node, double openDelay, double visibleDelay, double closeDelay, Tooltip tooltip) {
runInFX(() -> {
try {
// Java 8
Class<?> behaviorClass = Class.forName("javafx.scene.control.Tooltip$TooltipBehavior");
Constructor<?> behaviorConstructor = behaviorClass.getDeclaredConstructor(Duration.class, Duration.class, Duration.class, boolean.class);
behaviorConstructor.setAccessible(true);
Object behavior = behaviorConstructor.newInstance(new Duration(openDelay), new Duration(visibleDelay), new Duration(closeDelay), false);
Method installMethod = behaviorClass.getDeclaredMethod("install", Node.class, Tooltip.class);
installMethod.setAccessible(true);
installMethod.invoke(behavior, node, tooltip);
} catch (ReflectiveOperationException e) {
try {
// Java 9
Tooltip.class.getMethod("setShowDelay", Duration.class).invoke(tooltip, new Duration(openDelay));
Tooltip.class.getMethod("setShowDuration", Duration.class).invoke(tooltip, new Duration(visibleDelay));
Tooltip.class.getMethod("setHideDelay", Duration.class).invoke(tooltip, new Duration(closeDelay));
} catch (ReflectiveOperationException e2) {
e.addSuppressed(e2);
LOG.error("Cannot install tooltip", e);
}
Tooltip.install(node, tooltip);
}
});
}
public static void playAnimation(Node node, String animationKey, Timeline timeline) {
animationKey = "FXUTILS.ANIMATION." + animationKey;
Object oldTimeline = node.getProperties().get(animationKey);
@@ -957,6 +950,15 @@ public final class FXUtils {
});
}
public static void onClicked(Node node, Runnable action) {
node.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 1) {
action.run();
e.consume();
}
});
}
public static void copyText(String text) {
ClipboardContent content = new ClipboardContent();
content.putString(text);
@@ -987,7 +989,7 @@ public final class FXUtils {
if ("a".equals(element.getTagName())) {
String href = element.getAttribute("href");
Text text = new Text(element.getTextContent());
text.setOnMouseClicked(e -> {
onClicked(text, () -> {
String link = href;
try {
link = new URI(href).toASCIIString();
@@ -996,8 +998,8 @@ public final class FXUtils {
hyperlinkAction.accept(link);
});
text.setCursor(Cursor.HAND);
text.setFill(Color.web("#0070E0"));
text.setUnderline(true);
text.setFill(Color.web("#283593"));
texts.add(text);
} else if ("b".equals(element.getTagName())) {
Text text = new Text(element.getTextContent());
@@ -65,7 +65,6 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@@ -387,13 +386,13 @@ public class GameCrashWindow extends Stage {
gameDir.getStyleClass().setAll("two-line-item-second-large");
gameDir.setTitle(i18n("game.directory"));
gameDir.setSubtitle(launchOptions.getGameDir().getAbsolutePath());
runInFX(() -> FXUtils.installFastTooltip(gameDir, i18n("game.directory")));
FXUtils.installFastTooltip(gameDir, i18n("game.directory"));
TwoLineListItem javaDir = new TwoLineListItem();
javaDir.getStyleClass().setAll("two-line-item-second-large");
javaDir.setTitle(i18n("settings.game.java_directory"));
javaDir.setSubtitle(launchOptions.getJava().getBinary().toAbsolutePath().toString());
runInFX(() -> FXUtils.installFastTooltip(javaDir, i18n("settings.game.java_directory")));
FXUtils.installFastTooltip(javaDir, i18n("settings.game.java_directory"));
Label reasonTitle = new Label(i18n("game.crash.reason"));
reasonTitle.getStyleClass().add("two-line-item-second-large-title");
@@ -417,14 +416,14 @@ public class GameCrashWindow extends Stage {
HBox toolBar = new HBox();
{
JFXButton exportGameCrashInfoButton = FXUtils.newRaisedButton(i18n("logwindow.export_game_crash_logs"));
exportGameCrashInfoButton.setOnMouseClicked(e -> exportGameCrashInfo());
exportGameCrashInfoButton.setOnAction(e -> exportGameCrashInfo());
JFXButton logButton = FXUtils.newRaisedButton(i18n("logwindow.title"));
logButton.setOnMouseClicked(e -> showLogWindow());
logButton.setOnAction(e -> showLogWindow());
JFXButton helpButton = FXUtils.newRaisedButton(i18n("help"));
helpButton.setOnAction(e -> FXUtils.openLink("https://docs.hmcl.net/help.html"));
runInFX(() -> FXUtils.installFastTooltip(helpButton, i18n("logwindow.help")));
FXUtils.installFastTooltip(helpButton, i18n("logwindow.help"));
toolBar.setPadding(new Insets(8));
@@ -123,7 +123,7 @@ public final class HTMLRenderer {
if (hyperlink != null) {
URI target = resolveLink(hyperlink);
if (target != null) {
text.setOnMouseClicked(event -> onClickHyperlink.accept(target));
FXUtils.onClicked(text, () -> onClickHyperlink.accept(target));
text.setCursor(Cursor.HAND);
}
text.getStyleClass().add("html-hyperlink");
@@ -192,7 +192,7 @@ public final class HTMLRenderer {
if (hyperlink != null) {
URI target = resolveLink(hyperlink);
if (target != null) {
imageView.setOnMouseClicked(event -> onClickHyperlink.accept(target));
FXUtils.onClicked(imageView, () -> onClickHyperlink.accept(target));
imageView.setCursor(Cursor.HAND);
}
}
@@ -23,7 +23,6 @@ import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.css.PseudoClass;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
@@ -33,7 +32,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.*;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.setting.Theme;
@@ -60,8 +59,8 @@ public class InstallerItem extends Control {
private final ObjectProperty<InstalledState> versionProperty = new SimpleObjectProperty<>(this, "version", null);
private final ObjectProperty<State> resolvedStateProperty = new SimpleObjectProperty<>(this, "resolvedState", InstallableState.INSTANCE);
private final ObjectProperty<EventHandler<? super MouseEvent>> installActionProperty = new SimpleObjectProperty<>(this, "installAction");
private final ObjectProperty<EventHandler<? super MouseEvent>> removeActionProperty = new SimpleObjectProperty<>(this, "removeAction");
private final ObjectProperty<Runnable> onInstall = new SimpleObjectProperty<>(this, "onInstall");
private final ObjectProperty<Runnable> onRemove = new SimpleObjectProperty<>(this, "onRemove");
public interface State {
}
@@ -170,12 +169,28 @@ public class InstallerItem extends Control {
return resolvedStateProperty;
}
public ObjectProperty<EventHandler<? super MouseEvent>> installActionProperty() {
return installActionProperty;
public ObjectProperty<Runnable> onInstallProperty() {
return onInstall;
}
public ObjectProperty<EventHandler<? super MouseEvent>> removeActionProperty() {
return removeActionProperty;
public Runnable getOnInstall() {
return onInstall.get();
}
public void setOnInstall(Runnable onInstall) {
this.onInstall.set(onInstall);
}
public ObjectProperty<Runnable> onRemoveProperty() {
return onRemove;
}
public Runnable getOnRemove() {
return onRemove.get();
}
public void setOnRemove(Runnable onRemove) {
this.onRemove.set(onRemove);
}
@Override
@@ -371,7 +386,11 @@ public class InstallerItem extends Control {
removeButton.visibleProperty().bind(Bindings.createBooleanBinding(() -> control.resolvedStateProperty.get() instanceof InstalledState, control.resolvedStateProperty));
}
removeButton.managedProperty().bind(removeButton.visibleProperty());
removeButton.onMouseClickedProperty().bind(control.removeActionProperty);
removeButton.setOnAction(e -> {
Runnable onRemove = control.getOnRemove();
if (onRemove != null)
onRemove.run();
});
buttonsContainer.getChildren().add(removeButton);
JFXButton installButton = new JFXButton();
@@ -383,7 +402,7 @@ public class InstallerItem extends Control {
));
installButton.getStyleClass().add("toggle-icon4");
installButton.visibleProperty().bind(Bindings.createBooleanBinding(() -> {
if (control.installActionProperty.get() == null) {
if (control.getOnInstall() == null) {
return false;
}
@@ -396,18 +415,27 @@ public class InstallerItem extends Control {
}
return false;
}, control.resolvedStateProperty, control.installActionProperty));
}, control.resolvedStateProperty, control.onInstall));
installButton.managedProperty().bind(installButton.visibleProperty());
installButton.onMouseClickedProperty().bind(control.installActionProperty);
installButton.setOnAction(e -> {
Runnable onInstall = control.getOnInstall();
if (onInstall != null)
onInstall.run();
});
buttonsContainer.getChildren().add(installButton);
FXUtils.onChangeAndOperate(installButton.visibleProperty(), clickable -> {
if (clickable) {
container.onMouseClickedProperty().bind(control.installActionProperty);
container.setOnMouseClicked(event -> {
Runnable onInstall = control.getOnInstall();
if (onInstall != null && event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 1) {
onInstall.run();
event.consume();
}
});
pane.setCursor(Cursor.HAND);
} else {
container.onMouseClickedProperty().unbind();
container.onMouseClickedProperty().set(null);
container.setOnMouseClicked(null);
pane.setCursor(Cursor.DEFAULT);
}
});
@@ -70,7 +70,7 @@ public class ListPageSkin extends SkinBase<ListPage<?>> {
btnAdd.getStyleClass().add("jfx-button-raised-round");
btnAdd.setButtonType(JFXButton.ButtonType.RAISED);
btnAdd.setGraphic(SVG.PLUS.createIcon(Theme.whiteFill(), -1, -1));
btnAdd.setOnMouseClicked(e -> skinnable.add());
btnAdd.setOnAction(e -> skinnable.add());
JFXButton btnRefresh = new JFXButton();
FXUtils.setLimitWidth(btnRefresh, 40);
@@ -78,7 +78,7 @@ public class ListPageSkin extends SkinBase<ListPage<?>> {
btnRefresh.getStyleClass().add("jfx-button-raised-round");
btnRefresh.setButtonType(JFXButton.ButtonType.RAISED);
btnRefresh.setGraphic(SVG.REFRESH.createIcon(Theme.whiteFill(), -1, -1));
btnRefresh.setOnMouseClicked(e -> skinnable.refresh());
btnRefresh.setOnAction(e -> skinnable.refresh());
vBox.getChildren().setAll(btnAdd);
@@ -34,6 +34,7 @@ import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import org.jackhuang.hmcl.game.GameDumpGenerator;
@@ -322,6 +323,9 @@ public final class LogWindow extends Stage {
setGraphic(null);
setOnMouseClicked(event -> {
if (event.getButton() != MouseButton.PRIMARY)
return;
if (!event.isControlDown()) {
for (ListCell<Log> logListCell : selected) {
if (logListCell != this) {
@@ -340,6 +344,8 @@ public final class LogWindow extends Stage {
if (getItem() != null) {
getItem().setSelected(true);
}
event.consume();
});
}
@@ -32,7 +32,7 @@ public enum SVG {
CANCEL("M12 2C17.5 2 22 6.5 22 12S17.5 22 12 22 2 17.5 2 12 6.5 2 12 2M12 4C10.1 4 8.4 4.6 7.1 5.7L18.3 16.9C19.3 15.5 20 13.8 20 12C20 7.6 16.4 4 12 4M16.9 18.3L5.7 7.1C4.6 8.4 4 10.1 4 12C4 16.4 7.6 20 12 20C13.9 20 15.6 19.4 16.9 18.3Z"),
CHAT("M20,2A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H6L2,22V4C2,2.89 2.9,2 4,2H20M4,4V17.17L5.17,16H20V4H4M6,7H18V9H6V7M6,11H15V13H6V11Z"),
CLOSE("M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"),
COPY("M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"),
COPY("M15 16H7V6h8m.4-2H6.6A1.6 1.6 90 005 5.6V16.4a1.6 1.6 90 001.6 1.6h8.8A1.6 1.6 90 0017 16.4V5.6A1.6 1.6 90 0015.4 4M13 1H3.6A1.6 1.6 90 002 2.6V13h2V3H13V1Z"),
DOTS_VERTICAL("M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z"),
DOTS_HORIZONTAL("M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z"),
DELETE("M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"),
@@ -91,7 +91,7 @@ public abstract class ToolbarListPageSkin<T extends ListPageBase<? extends Node>
ret.textFillProperty().bind(Theme.foregroundFillBinding());
ret.setGraphic(wrap(svg.createIcon(Theme.foregroundFillBinding(), -1, -1)));
ret.setText(text);
ret.setOnMouseClicked(e -> onClick.run());
ret.setOnAction(e -> onClick.run());
return ret;
}
@@ -100,7 +100,7 @@ public abstract class ToolbarListPageSkin<T extends ListPageBase<? extends Node>
ret.getStyleClass().add("jfx-tool-bar-button");
ret.setGraphic(wrap(svg.createIcon(Theme.blackFill(), -1, -1)));
ret.setText(text);
ret.setOnMouseClicked(e -> onClick.run());
ret.setOnAction(e -> onClick.run());
return ret;
}
@@ -110,7 +110,7 @@ public abstract class ToolbarListPageSkin<T extends ListPageBase<? extends Node>
ret.textFillProperty().bind(Theme.foregroundFillBinding());
ret.setGraphic(wrap(svg.createIcon(Theme.foregroundFillBinding(), -1, -1)));
FXUtils.installFastTooltip(ret, tooltip);
ret.setOnMouseClicked(e -> onClick.run());
ret.setOnAction(e -> onClick.run());
return ret;
}
@@ -0,0 +1,123 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2024 huangyuhui <huanghongxun2008@126.com> 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 <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.ui;
import javafx.scene.Node;
import javafx.scene.control.Tooltip;
import javafx.util.Duration;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* @author Glavo
*/
public class TooltipInstaller {
public static final TooltipInstaller INSTALLER;
static {
TooltipInstaller installer = null;
try {
installer = new NewInstaller();
} catch (Throwable e) {
try {
installer = new OldInstaller();
} catch (Throwable e2) {
e2.addSuppressed(e);
LOG.warning("Failed to initialize TooltipInstaller", e2);
}
}
INSTALLER = installer != null ? installer : new TooltipInstaller();
}
TooltipInstaller() {
}
public void installTooltip(Node node, Duration showDelay, Duration showDuration, Duration hideDelay, Tooltip tooltip) {
Tooltip.install(node, tooltip);
}
// For Java 8
private static final class OldInstaller extends TooltipInstaller {
private static final Constructor<?> createTooltipBehavior;
private static final Method installTooltipBehavior;
static {
try {
Class<?> behaviorClass = Class.forName("javafx.scene.control.Tooltip$TooltipBehavior");
createTooltipBehavior = behaviorClass.getDeclaredConstructor(Duration.class, Duration.class, Duration.class, boolean.class);
createTooltipBehavior.setAccessible(true);
installTooltipBehavior = behaviorClass.getDeclaredMethod("install", Node.class, Tooltip.class);
installTooltipBehavior.setAccessible(true);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
@Override
public void installTooltip(Node node, Duration showDelay, Duration showDuration, Duration hideDelay, Tooltip tooltip) {
try {
Object behavior = createTooltipBehavior.newInstance(showDelay, showDuration, hideDelay, false);
installTooltipBehavior.invoke(behavior, node, tooltip);
} catch (ReflectiveOperationException e) {
LOG.warning("Failed to set tooltip show delay", e);
Tooltip.install(node, tooltip);
}
}
}
// For Java 9+
private static final class NewInstaller extends TooltipInstaller {
private static final MethodHandle setTooltipShowDelay;
private static final MethodHandle setTooltipShowDuration;
private static final MethodHandle setTooltipHideDelay;
static {
try {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
MethodType methodType = MethodType.methodType(void.class, Duration.class);
setTooltipShowDelay = lookup.findVirtual(Tooltip.class, "setShowDelay", methodType);
setTooltipShowDuration = lookup.findVirtual(Tooltip.class, "setShowDuration", methodType);
setTooltipHideDelay = lookup.findVirtual(Tooltip.class, "setHideDelay", methodType);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
@Override
public void installTooltip(Node node, Duration showDelay, Duration showDuration, Duration hideDelay, Tooltip tooltip) {
try {
setTooltipShowDelay.invokeExact(tooltip, showDelay);
setTooltipShowDuration.invokeExact(tooltip, showDuration);
setTooltipHideDelay.invokeExact(tooltip, hideDelay);
} catch (Throwable e) {
LOG.warning("Failed to set tooltip show delay", e);
}
Tooltip.install(node, tooltip);
}
}
}
@@ -42,10 +42,9 @@ import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.construct.SpinnerPane;
import org.jackhuang.hmcl.util.javafx.BindingMapping;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class AccountListItemSkin extends SkinBase<AccountListItem> {
public final class AccountListItemSkin extends SkinBase<AccountListItem> {
public AccountListItemSkin(AccountListItem skinnable) {
super(skinnable);
@@ -94,7 +93,7 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
JFXButton btnMove = new JFXButton();
SpinnerPane spinnerMove = new SpinnerPane();
spinnerMove.getStyleClass().add("small-spinner-pane");
btnMove.setOnMouseClicked(e -> {
btnMove.setOnAction(e -> {
Account account = skinnable.getAccount();
Accounts.getAccounts().remove(account);
if (account.isPortable()) {
@@ -118,10 +117,10 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
btnMove.getStyleClass().add("toggle-icon4");
if (skinnable.getAccount().isPortable()) {
btnMove.setGraphic(SVG.EARTH.createIcon(Theme.blackFill(), -1, -1));
runInFX(() -> FXUtils.installFastTooltip(btnMove, i18n("account.move_to_global")));
FXUtils.installFastTooltip(btnMove, i18n("account.move_to_global"));
} else {
btnMove.setGraphic(SVG.EXPORT.createIcon(Theme.blackFill(), -1, -1));
runInFX(() -> FXUtils.installFastTooltip(btnMove, i18n("account.move_to_portable")));
FXUtils.installFastTooltip(btnMove, i18n("account.move_to_portable"));
}
spinnerMove.setContent(btnMove);
right.getChildren().add(spinnerMove);
@@ -129,7 +128,7 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
JFXButton btnRefresh = new JFXButton();
SpinnerPane spinnerRefresh = new SpinnerPane();
spinnerRefresh.getStyleClass().setAll("small-spinner-pane");
btnRefresh.setOnMouseClicked(e -> {
btnRefresh.setOnAction(e -> {
spinnerRefresh.showSpinner();
skinnable.refreshAsync()
.whenComplete(Schedulers.javafx(), ex -> {
@@ -143,13 +142,13 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
});
btnRefresh.getStyleClass().add("toggle-icon4");
btnRefresh.setGraphic(SVG.REFRESH.createIcon(Theme.blackFill(), -1, -1));
runInFX(() -> FXUtils.installFastTooltip(btnRefresh, i18n("button.refresh")));
FXUtils.installFastTooltip(btnRefresh, i18n("button.refresh"));
spinnerRefresh.setContent(btnRefresh);
right.getChildren().add(spinnerRefresh);
JFXButton btnUpload = new JFXButton();
SpinnerPane spinnerUpload = new SpinnerPane();
btnUpload.setOnMouseClicked(e -> {
btnUpload.setOnAction(e -> {
Task<?> uploadTask = skinnable.uploadSkin();
if (uploadTask != null) {
spinnerUpload.showSpinner();
@@ -160,7 +159,7 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
});
btnUpload.getStyleClass().add("toggle-icon4");
btnUpload.setGraphic(SVG.HANGER.createIcon(Theme.blackFill(), -1, -1));
runInFX(() -> FXUtils.installFastTooltip(btnUpload, i18n("account.skin.upload")));
FXUtils.installFastTooltip(btnUpload, i18n("account.skin.upload"));
spinnerUpload.managedProperty().bind(spinnerUpload.visibleProperty());
spinnerUpload.visibleProperty().bind(skinnable.canUploadSkin());
spinnerUpload.setContent(btnUpload);
@@ -170,18 +169,19 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
JFXButton btnCopyUUID = new JFXButton();
SpinnerPane spinnerCopyUUID = new SpinnerPane();
spinnerCopyUUID.getStyleClass().add("small-spinner-pane");
btnCopyUUID.setOnMouseClicked(e -> FXUtils.copyText(skinnable.getAccount().getUUID().toString()));
btnUpload.getStyleClass().add("toggle-icon4");
btnCopyUUID.setOnAction(e -> FXUtils.copyText(skinnable.getAccount().getUUID().toString()));
btnCopyUUID.setGraphic(SVG.COPY.createIcon(Theme.blackFill(), -1, -1));
runInFX(() -> FXUtils.installFastTooltip(btnCopyUUID, i18n("account.copy_uuid")));
FXUtils.installFastTooltip(btnCopyUUID, i18n("account.copy_uuid"));
spinnerCopyUUID.setContent(btnCopyUUID);
right.getChildren().add(spinnerCopyUUID);
JFXButton btnRemove = new JFXButton();
btnRemove.setOnMouseClicked(e -> Controllers.confirm(i18n("button.remove.confirm"), i18n("button.remove"), skinnable::remove, null));
btnRemove.setOnAction(e -> Controllers.confirm(i18n("button.remove.confirm"), i18n("button.remove"), skinnable::remove, null));
btnRemove.getStyleClass().add("toggle-icon4");
BorderPane.setAlignment(btnRemove, Pos.CENTER);
btnRemove.setGraphic(SVG.DELETE.createIcon(Theme.blackFill(), -1, -1));
runInFX(() -> FXUtils.installFastTooltip(btnRemove, i18n("button.delete")));
btnRemove.setGraphic(SVG.DELETE_OUTLINE.createIcon(Theme.blackFill(), -1, -1));
FXUtils.installFastTooltip(btnRemove, i18n("button.delete"));
right.getChildren().add(btnRemove);
root.setRight(right);
@@ -147,7 +147,7 @@ public final class AddAuthlibInjectorServerPane extends TransitionPane implement
confirmServerPane.setActions(prevButton, cancelButton, finishButton);
}
this.setContent(addServerPane, ContainerAnimations.NONE.getAnimationProducer());
this.setContent(addServerPane, ContainerAnimations.NONE);
lblCreationWarning.maxWidthProperty().bind(((FlowPane) lblCreationWarning.getParent()).widthProperty());
btnAddNext.disableProperty().bind(txtServerUrl.textProperty().isEmpty());
@@ -198,7 +198,7 @@ public final class AddAuthlibInjectorServerPane extends TransitionPane implement
lblServerWarning.setVisible("http".equals(NetworkUtils.toURL(serverBeingAdded.getUrl()).getProtocol()));
this.setContent(confirmServerPane, ContainerAnimations.SWIPE_LEFT.getAnimationProducer());
this.setContent(confirmServerPane, ContainerAnimations.SWIPE_LEFT);
} else {
LOG.warning("Failed to resolve auth server: " + url, exception);
lblCreationWarning.setText(resolveFetchExceptionMessage(exception));
@@ -208,7 +208,7 @@ public final class AddAuthlibInjectorServerPane extends TransitionPane implement
}
private void onAddPrev() {
this.setContent(addServerPane, ContainerAnimations.SWIPE_RIGHT.getAnimationProducer());
this.setContent(addServerPane, ContainerAnimations.SWIPE_RIGHT);
}
private void onAddFinish() {
@@ -297,7 +297,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
hintPane.setSegment(i18n("account.methods.microsoft.hint"));
}
});
hintPane.setOnMouseClicked(e -> {
FXUtils.onClicked(hintPane, () -> {
if (deviceCode.get() != null) {
FXUtils.copyText(deviceCode.get().getUserCode());
}
@@ -317,7 +317,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
JFXHyperlink deauthorizeLink = new JFXHyperlink(i18n("account.methods.microsoft.deauthorize"));
deauthorizeLink.setExternalLink("https://account.live.com/consent/Edit?client_id=000000004C794E0A");
JFXHyperlink forgotpasswordLink = new JFXHyperlink(i18n("account.methods.forgot_password"));
forgotpasswordLink.setExternalLink("https://www.minecraft.net/password/forgot");
forgotpasswordLink.setExternalLink("https://account.live.com/ResetPassword.aspx");
JFXHyperlink createProfileLink = new JFXHyperlink(i18n("account.methods.microsoft.makegameidsettings"));
createProfileLink.setExternalLink("https://www.minecraft.net/msaprofile/mygames/editprofile");
box.getChildren().setAll(profileLink, birthLink, purchaseLink, deauthorizeLink, forgotpasswordLink, createProfileLink);
@@ -510,7 +510,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
if (factory instanceof OfflineAccountFactory) {
txtUsername.setPromptText(i18n("account.methods.offline.name.special_characters"));
runInFX(() -> FXUtils.installFastTooltip(txtUsername, i18n("account.methods.offline.name.special_characters")));
FXUtils.installFastTooltip(txtUsername, i18n("account.methods.offline.name.special_characters"));
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.microsoft.purchase"));
purchaseLink.setExternalLink(YggdrasilService.PURCHASE_URL);
@@ -658,7 +658,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
TexturesLoader.bindAvatar(portraitCanvas, service, profile.getId());
IconedItem accountItem = new IconedItem(portraitCanvas, profile.getName());
accountItem.setOnMouseClicked(e -> {
FXUtils.onClicked(accountItem, () -> {
selectedProfile = profile;
latch.countDown();
});
@@ -58,7 +58,7 @@ public class OAuthAccountLoginDialog extends DialogPane {
);
}
});
hintPane.setOnMouseClicked(e -> {
FXUtils.onClicked(hintPane, () -> {
if (deviceCode.get() != null) {
FXUtils.copyText(deviceCode.get().getUserCode());
}
@@ -28,9 +28,9 @@ import javafx.scene.control.Label;
import javafx.scene.input.DragEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.*;
import moe.mickey.minecraft.skin.fx.SkinCanvas;
import moe.mickey.minecraft.skin.fx.animation.SkinAniRunning;
import moe.mickey.minecraft.skin.fx.animation.SkinAniWavingArms;
import org.jackhuang.hmcl.ui.skin.SkinCanvas;
import org.jackhuang.hmcl.ui.skin.animation.SkinAniRunning;
import org.jackhuang.hmcl.ui.skin.animation.SkinAniWavingArms;
import org.jackhuang.hmcl.auth.offline.OfflineAccount;
import org.jackhuang.hmcl.auth.offline.Skin;
import org.jackhuang.hmcl.auth.yggdrasil.TextureModel;
@@ -1,6 +1,6 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> 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
@@ -27,165 +27,225 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public enum ContainerAnimations {
NONE(c -> {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
}, c -> Collections.emptyList()),
public enum ContainerAnimations implements AnimationProducer {
NONE {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Collections.emptyList();
}
},
/**
* A fade between the old and new view
*/
FADE(c -> {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(0);
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
FADE {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(0);
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getPreviousNode().opacityProperty(), 1, Interpolator.EASE_BOTH),
new KeyValue(c.getCurrentNode().opacityProperty(), 0, Interpolator.EASE_BOTH)),
new KeyFrame(c.getDuration(),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getCurrentNode().opacityProperty(), 1, Interpolator.EASE_BOTH)))),
new KeyValue(c.getCurrentNode().opacityProperty(), 1, Interpolator.EASE_BOTH)));
}
},
/**
* A fade between the old and new view
*/
FADE_IN(c -> {
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(0);
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
FADE_IN {
@Override
public void init(AnimationHandler c) {
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(0);
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getCurrentNode().opacityProperty(), 0, FXUtils.SINE)),
new KeyFrame(c.getDuration(),
new KeyValue(c.getCurrentNode().opacityProperty(), 1, FXUtils.SINE)))),
new KeyValue(c.getCurrentNode().opacityProperty(), 1, FXUtils.SINE)));
}
},
/**
* A fade between the old and new view
*/
FADE_OUT(c -> {
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
FADE_OUT {
@Override
public void init(AnimationHandler c) {
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getCurrentNode().opacityProperty(), 1, FXUtils.SINE)),
new KeyFrame(c.getDuration(),
new KeyValue(c.getCurrentNode().opacityProperty(), 0, FXUtils.SINE)))),
new KeyValue(c.getCurrentNode().opacityProperty(), 0, FXUtils.SINE)));
}
},
/**
* A zoom effect
*/
ZOOM_IN(c -> {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
ZOOM_IN {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getPreviousNode().scaleXProperty(), 1, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().scaleYProperty(), 1, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().opacityProperty(), 1, Interpolator.EASE_BOTH)),
new KeyFrame(c.getDuration(),
new KeyValue(c.getPreviousNode().scaleXProperty(), 4, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().scaleYProperty(), 4, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH)))),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH)));
}
},
/**
* A zoom effect
*/
ZOOM_OUT(c -> {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
}, c ->
(Arrays.asList(new KeyFrame(Duration.ZERO,
ZOOM_OUT {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setTranslateX(0);
c.getPreviousNode().setTranslateY(0);
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(1);
c.getCurrentNode().setTranslateX(0);
c.getCurrentNode().setTranslateY(0);
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getPreviousNode().scaleXProperty(), 1, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().scaleYProperty(), 1, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().opacityProperty(), 1, Interpolator.EASE_BOTH)),
new KeyFrame(c.getDuration(),
new KeyValue(c.getPreviousNode().scaleXProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().scaleYProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH))))),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH)));
}
},
/**
* A swipe effect
*/
SWIPE_LEFT(c -> {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
SWIPE_LEFT {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getCurrentNode().translateXProperty(), c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH)),
new KeyFrame(c.getDuration(),
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), -c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH)))),
new KeyValue(c.getPreviousNode().translateXProperty(), -c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH)));
}
},
/**
* A swipe effect
*/
SWIPE_RIGHT(c -> {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(-c.getCurrentRoot().getWidth());
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
SWIPE_RIGHT {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(-c.getCurrentRoot().getWidth());
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getCurrentNode().translateXProperty(), -c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH)),
new KeyFrame(c.getDuration(),
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH)))),
new KeyValue(c.getPreviousNode().translateXProperty(), c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH)));
}
},
SWIPE_LEFT_FADE_SHORT(c -> {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
SWIPE_LEFT_FADE_SHORT {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getCurrentNode().translateXProperty(), 50, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getCurrentNode().opacityProperty(), 0, Interpolator.EASE_BOTH),
@@ -194,19 +254,26 @@ public enum ContainerAnimations {
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), -50, Interpolator.EASE_BOTH),
new KeyValue(c.getCurrentNode().opacityProperty(), 1, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH)))),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH)));
}
},
SWIPE_RIGHT_FADE_SHORT(c -> {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
}, c ->
Arrays.asList(new KeyFrame(Duration.ZERO,
SWIPE_RIGHT_FADE_SHORT {
@Override
public void init(AnimationHandler c) {
c.getPreviousNode().setScaleX(1);
c.getPreviousNode().setScaleY(1);
c.getPreviousNode().setOpacity(0);
c.getPreviousNode().setTranslateX(0);
c.getCurrentNode().setScaleX(1);
c.getCurrentNode().setScaleY(1);
c.getCurrentNode().setOpacity(1);
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
}
@Override
public List<KeyFrame> animate(AnimationHandler c) {
return Arrays.asList(new KeyFrame(Duration.ZERO,
new KeyValue(c.getCurrentNode().translateXProperty(), -50, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getCurrentNode().opacityProperty(), 0, Interpolator.EASE_BOTH),
@@ -215,38 +282,12 @@ public enum ContainerAnimations {
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().translateXProperty(), 50, Interpolator.EASE_BOTH),
new KeyValue(c.getCurrentNode().opacityProperty(), 1, Interpolator.EASE_BOTH),
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH))));
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH)));
}
};
private final AnimationProducer animationProducer;
private ContainerAnimations opposite;
ContainerAnimations(Consumer<AnimationHandler> init, Function<AnimationHandler, List<KeyFrame>> animationProducer) {
this.animationProducer = new AnimationProducer() {
@Override
public void init(AnimationHandler handler) {
init.accept(handler);
}
@Override
public List<KeyFrame> animate(AnimationHandler handler) {
return animationProducer.apply(handler);
}
@Override
public @Nullable AnimationProducer opposite() {
return opposite != null ? opposite.getAnimationProducer() : null;
}
};
}
public AnimationProducer getAnimationProducer() {
return animationProducer;
}
public ContainerAnimations getOpposite() {
return opposite;
}
static {
NONE.opposite = NONE;
FADE.opposite = FADE;
@@ -257,4 +298,15 @@ public enum ContainerAnimations {
ZOOM_IN.opposite = ZOOM_OUT;
ZOOM_OUT.opposite = ZOOM_IN;
}
@Override
public abstract void init(AnimationHandler handler);
@Override
public abstract List<KeyFrame> animate(AnimationHandler handler);
@Override
public @Nullable ContainerAnimations opposite() {
return opposite;
}
}
@@ -25,7 +25,6 @@ import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.util.Pair;
@@ -42,7 +41,7 @@ public class AdvancedListItem extends Control {
public AdvancedListItem() {
getStyleClass().add("advanced-list-item");
addEventHandler(MouseEvent.MOUSE_CLICKED, e -> fireEvent(new ActionEvent()));
FXUtils.onClicked(this, () -> fireEvent(new ActionEvent()));
}
public Node getLeftGraphic() {
@@ -17,21 +17,36 @@
*/
package org.jackhuang.hmcl.ui.construct;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.TextFlow;
import org.jackhuang.hmcl.setting.Theme;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.SVG;
public class AnnouncementCard extends VBox {
public final class AnnouncementCard extends VBox {
public AnnouncementCard(String title, String content) {
TextFlow tf = FXUtils.segmentToTextFlow(content, Controllers::onHyperlinkAction);
public AnnouncementCard(String title, String content, Runnable onClose) {
TextFlow body = FXUtils.segmentToTextFlow(content, Controllers::onHyperlinkAction);
body.setLineSpacing(4);
Label label = new Label(title);
label.getStyleClass().add("title");
getChildren().setAll(label, tf);
setSpacing(14);
BorderPane titleBar = new BorderPane();
titleBar.getStyleClass().add("title");
titleBar.setLeft(new Label(title));
if (onClose != null) {
Node hideNode = SVG.CLOSE.createIcon(Theme.blackFill(), 20, 20);
hideNode.setOnMouseClicked(e -> onClose.run());
hideNode.setCursor(Cursor.HAND);
titleBar.setRight(hideNode);
}
getChildren().setAll(titleBar, body);
setSpacing(16);
getStyleClass().addAll("card", "announcement");
}
}
@@ -25,9 +25,6 @@ import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
@@ -139,7 +136,7 @@ final class ComponentListCell extends StackPane {
container.getChildren().setAll(content);
groupNode.getChildren().add(container);
EventHandler<Event> onExpand = e -> {
Runnable onExpand = () -> {
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
expandAnimation.stop();
}
@@ -182,8 +179,8 @@ final class ComponentListCell extends StackPane {
});
};
headerRippler.setOnMouseClicked(onExpand);
expandButton.setOnAction((EventHandler<ActionEvent>) (Object) onExpand);
FXUtils.onClicked(headerRippler, onExpand);
expandButton.setOnAction(e -> onExpand.run());
expandedProperty().addListener((a, b, newValue) -> expandIcon.setRotate(newValue ? 180 : 0));
@@ -60,7 +60,7 @@ public class FileItem extends BorderPane {
JFXButton right = new JFXButton();
right.setGraphic(SVG.PENCIL.createIcon(Theme.blackFill(), 15, 15));
right.getStyleClass().add("toggle-icon4");
right.setOnMouseClicked(e -> onExplore());
right.setOnAction(e -> onExplore());
FXUtils.installFastTooltip(right, i18n("button.edit"));
setRight(right);
@@ -21,6 +21,7 @@ import static javafx.collections.FXCollections.emptyObservableList;
import static javafx.collections.FXCollections.observableList;
import static javafx.collections.FXCollections.singletonObservableList;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.util.javafx.BindingMapping;
import com.jfoenix.controls.JFXComboBox;
@@ -34,6 +35,8 @@ public class FontComboBox extends JFXComboBox<String> {
private boolean loaded = false;
public FontComboBox() {
setMinWidth(260);
styleProperty().bind(Bindings.concat("-fx-font-family: \"", valueProperty(), "\""));
setCellFactory(listView -> new JFXListCell<String>() {
@@ -51,7 +54,7 @@ public class FontComboBox extends JFXComboBox<String> {
itemsProperty().bind(BindingMapping.of(valueProperty())
.map(value -> value == null ? emptyObservableList() : singletonObservableList(value)));
setOnMouseClicked(e -> {
FXUtils.onClicked(this, () -> {
if (loaded)
return;
itemsProperty().unbind();
@@ -30,9 +30,9 @@ public class IconedMenuItem extends IconedItem {
getStyleClass().setAll("iconed-menu-item");
if (popup == null) {
setOnMouseClicked(e -> action.run());
FXUtils.onClicked(this, action);
} else {
setOnMouseClicked(e -> {
FXUtils.onClicked(this, () -> {
action.run();
popup.hide();
});
@@ -23,12 +23,12 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
@@ -44,8 +44,8 @@ public final class ImagePickerItem extends BorderPane {
private final ImageView imageView;
private final StringProperty title = new SimpleStringProperty(this, "title");
private final ObjectProperty<EventHandler<? super MouseEvent>> onSelectButtonClicked = new SimpleObjectProperty<>(this, "onSelectButtonClicked");
private final ObjectProperty<EventHandler<? super MouseEvent>> onDeleteButtonClicked = new SimpleObjectProperty<>(this, "onDeleteButtonClicked");
private final ObjectProperty<EventHandler<ActionEvent>> onSelectButtonClicked = new SimpleObjectProperty<>(this, "onSelectButtonClicked");
private final ObjectProperty<EventHandler<ActionEvent>> onDeleteButtonClicked = new SimpleObjectProperty<>(this, "onDeleteButtonClicked");
private final ObjectProperty<Image> image = new SimpleObjectProperty<>(this, "image");
public ImagePickerItem() {
@@ -55,12 +55,12 @@ public final class ImagePickerItem extends BorderPane {
JFXButton selectButton = new JFXButton();
selectButton.setGraphic(SVG.PENCIL.createIcon(Theme.blackFill(), 20, 20));
selectButton.onMouseClickedProperty().bind(onSelectButtonClicked);
selectButton.onActionProperty().bind(onSelectButtonClicked);
selectButton.getStyleClass().add("toggle-icon4");
JFXButton deleteButton = new JFXButton();
deleteButton.setGraphic(SVG.CLOSE.createIcon(Theme.blackFill(), 20, 20));
deleteButton.onMouseClickedProperty().bind(onDeleteButtonClicked);
deleteButton.onActionProperty().bind(onDeleteButtonClicked);
deleteButton.getStyleClass().add("toggle-icon4");
FXUtils.installFastTooltip(selectButton, i18n("button.edit"));
@@ -93,27 +93,27 @@ public final class ImagePickerItem extends BorderPane {
this.title.set(title);
}
public EventHandler<? super MouseEvent> getOnSelectButtonClicked() {
public EventHandler<ActionEvent> getOnSelectButtonClicked() {
return onSelectButtonClicked.get();
}
public ObjectProperty<EventHandler<? super MouseEvent>> onSelectButtonClickedProperty() {
public ObjectProperty<EventHandler<ActionEvent>> onSelectButtonClickedProperty() {
return onSelectButtonClicked;
}
public void setOnSelectButtonClicked(EventHandler<? super MouseEvent> onSelectButtonClicked) {
public void setOnSelectButtonClicked(EventHandler<ActionEvent> onSelectButtonClicked) {
this.onSelectButtonClicked.set(onSelectButtonClicked);
}
public EventHandler<? super MouseEvent> getOnDeleteButtonClicked() {
public EventHandler<ActionEvent> getOnDeleteButtonClicked() {
return onDeleteButtonClicked.get();
}
public ObjectProperty<EventHandler<? super MouseEvent>> onDeleteButtonClickedProperty() {
public ObjectProperty<EventHandler<ActionEvent>> onDeleteButtonClickedProperty() {
return onDeleteButtonClicked;
}
public void setOnDeleteButtonClicked(EventHandler<? super MouseEvent> onDeleteButtonClicked) {
public void setOnDeleteButtonClicked(EventHandler<ActionEvent> onDeleteButtonClicked) {
this.onDeleteButtonClicked.set(onDeleteButtonClicked);
}
@@ -126,7 +126,7 @@ public class Navigator extends TransitionPane {
if (obj instanceof AnimationProducer) {
setContent(node, (AnimationProducer) obj);
} else {
setContent(node, ContainerAnimations.NONE.getAnimationProducer());
setContent(node, ContainerAnimations.NONE);
}
NavigationEvent navigated = new NavigationEvent(this, node, Navigation.NavigationDirection.PREVIOUS, NavigationEvent.NAVIGATED);
@@ -61,9 +61,7 @@ public class OptionToggleButton extends StackPane {
toggleButton.setSize(8);
FXUtils.setLimitHeight(toggleButton, 30);
container.setOnMouseClicked(e -> {
toggleButton.setSelected(!toggleButton.isSelected());
});
FXUtils.onClicked(container, () -> toggleButton.setSelected(!toggleButton.isSelected()));
FXUtils.onChangeAndOperate(subtitleProperty(), subtitle -> {
if (StringUtils.isNotBlank(subtitle)) {
@@ -32,7 +32,6 @@ import javafx.scene.layout.StackPane;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
import org.jackhuang.hmcl.ui.animation.TransitionPane;
import org.jackhuang.hmcl.util.javafx.BindingMapping;
@DefaultProperty("content")
public class SpinnerPane extends Control {
@@ -101,18 +100,19 @@ public class SpinnerPane extends Control {
return onFailedActionProperty().get();
}
private ObjectProperty<EventHandler<Event>> onFailedAction = new SimpleObjectProperty<EventHandler<Event>>(this, "onFailedAction") {
private final ObjectProperty<EventHandler<Event>> onFailedAction = new SimpleObjectProperty<EventHandler<Event>>(this, "onFailedAction") {
@Override
protected void invalidated() {
setEventHandler(FAILED_ACTION, get());
}
};
@Override
protected Skin createDefaultSkin() {
protected SkinBase<SpinnerPane> createDefaultSkin() {
return new Skin(this);
}
private static class Skin extends SkinBase<SpinnerPane> {
private static final class Skin extends SkinBase<SpinnerPane> {
private final JFXSpinner spinner = new JFXSpinner();
private final StackPane contentPane = new StackPane();
private final StackPane topPane = new StackPane();
@@ -122,20 +122,18 @@ public class SpinnerPane extends Control {
@SuppressWarnings("FieldCanBeLocal") // prevent from gc.
private final InvalidationListener observer;
protected Skin(SpinnerPane control) {
Skin(SpinnerPane control) {
super(control);
topPane.getChildren().setAll(spinner);
topPane.getStyleClass().add("notice-pane");
failedPane.getStyleClass().add("notice-pane");
failedPane.getChildren().setAll(failedReasonLabel);
failedPane.onMouseClickedProperty().bind(
BindingMapping.of(control.onFailedAction)
.map(actionHandler -> (e -> {
if (actionHandler != null) {
actionHandler.handle(new Event(FAILED_ACTION));
}
})));
FXUtils.onClicked(failedPane, () -> {
EventHandler<Event> action = control.getOnFailedAction();
if (action != null)
action.handle(new Event(FAILED_ACTION));
});
FXUtils.onChangeAndOperate(getSkinnable().content, newValue -> {
if (newValue == null) {
@@ -148,12 +146,12 @@ public class SpinnerPane extends Control {
observer = FXUtils.observeWeak(() -> {
if (getSkinnable().getFailedReason() != null) {
root.setContent(failedPane, ContainerAnimations.FADE.getAnimationProducer());
root.setContent(failedPane, ContainerAnimations.FADE);
failedReasonLabel.setText(getSkinnable().getFailedReason());
} else if (getSkinnable().isLoading()) {
root.setContent(topPane, ContainerAnimations.FADE.getAnimationProducer());
root.setContent(topPane, ContainerAnimations.FADE);
} else {
root.setContent(contentPane, ContainerAnimations.FADE.getAnimationProducer());
root.setContent(contentPane, ContainerAnimations.FADE);
}
}, getSkinnable().loadingProperty(), getSkinnable().failedReasonProperty());
}
@@ -30,7 +30,6 @@ import javafx.geometry.Insets;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.transform.Rotate;
@@ -594,11 +593,9 @@ public class TabHeader extends Control implements TabControl, PageAware {
FXUtils.onChangeAndOperate(tab.selectedProperty(), selected -> inner.pseudoClassStateChanged(SELECTED_PSEUDOCLASS_STATE, selected));
this.setOnMouseClicked(event -> {
if (event.getButton() == MouseButton.PRIMARY) {
this.setOpacity(1);
getSkinnable().getSelectionModel().select(tab);
}
FXUtils.onClicked(this, () -> {
this.setOpacity(1);
getSkinnable().getSelectionModel().select(tab);
});
}
}
@@ -30,6 +30,8 @@ import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.input.DragEvent;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
@@ -144,6 +146,18 @@ public class DecoratorController {
// press ESC to go back
onEscPressed(navigator, this::back);
try {
// For JavaFX 12+
MouseButton button = MouseButton.valueOf("BACK");
navigator.addEventFilter(MouseEvent.MOUSE_CLICKED, e -> {
if (e.getButton() == button) {
back();
e.consume();
}
});
} catch (IllegalArgumentException ignored) {
}
}
public Decorator getDecorator() {
@@ -443,7 +457,7 @@ public class DecoratorController {
public void startWizard(WizardProvider wizardProvider, String category) {
FXUtils.checkFxUserThread();
navigator.navigate(new DecoratorWizardDisplayer(wizardProvider, category), ContainerAnimations.FADE.getAnimationProducer());
navigator.navigate(new DecoratorWizardDisplayer(wizardProvider, category), ContainerAnimations.FADE);
}
// ==== Authlib Injector DnD ====
@@ -174,11 +174,11 @@ public class DecoratorSkin extends SkinBase<Decorator> {
if (s.isAnimate()) {
AnimationProducer animation;
if (skinnable.getNavigationDirection() == Navigation.NavigationDirection.NEXT) {
animation = ContainerAnimations.SWIPE_LEFT_FADE_SHORT.getAnimationProducer();
animation = ContainerAnimations.SWIPE_LEFT_FADE_SHORT;
} else if (skinnable.getNavigationDirection() == Navigation.NavigationDirection.PREVIOUS) {
animation = ContainerAnimations.SWIPE_RIGHT_FADE_SHORT.getAnimationProducer();
animation = ContainerAnimations.SWIPE_RIGHT_FADE_SHORT;
} else {
animation = ContainerAnimations.FADE.getAnimationProducer();
animation = ContainerAnimations.FADE;
}
skinnable.setNavigationDirection(Navigation.NavigationDirection.START);
navBarPane.setContent(node, animation);
@@ -36,7 +36,7 @@ public abstract class DecoratorTabPage extends DecoratorTransitionPage implement
if (newValue.getNode() != null) {
onNavigating(getCurrentPage());
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigation.NavigationDirection.NEXT, Navigator.NavigationEvent.NAVIGATING));
navigate(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
navigate(newValue.getNode(), ContainerAnimations.FADE);
onNavigated(getCurrentPage());
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigation.NavigationDirection.NEXT, Navigator.NavigationEvent.NAVIGATED));
}
@@ -74,7 +74,7 @@ public class DecoratorWizardDisplayer extends DecoratorTransitionPage implements
@Override
public void navigateTo(Node page, Navigation.NavigationDirection nav) {
displayer.navigateTo(page, nav);
navigate(page, nav.getAnimation().getAnimationProducer());
navigate(page, nav.getAnimation());
String prefix = category == null ? "" : category + " - ";
@@ -59,7 +59,7 @@ class AdditionalInstallersPage extends InstallersPage {
for (InstallerItem library : group.getLibraries()) {
String libraryId = library.getLibraryId();
if (libraryId.equals("game")) continue;
library.removeActionProperty().set(e -> {
library.setOnRemove(() -> {
controller.getSettings().put(libraryId, new UpdateInstallerWizardProvider.RemoveVersionAction(libraryId));
reload();
});
@@ -97,7 +97,7 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
tab.select(newGameTab);
FXUtils.onChangeAndOperate(tab.getSelectionModel().selectedItemProperty(), newValue -> {
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE);
});
{
@@ -69,7 +69,7 @@ public class InstallersPage extends Control implements WizardPage {
for (InstallerItem library : group.getLibraries()) {
String libraryId = library.getLibraryId();
if (libraryId.equals(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId())) continue;
library.installActionProperty().set(e -> {
library.setOnInstall(() -> {
if (LibraryAnalyzer.LibraryType.FABRIC_API.getPatchId().equals(libraryId)) {
Controllers.dialog(i18n("install.installer.fabric-api.warning"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING);
}
@@ -77,7 +77,7 @@ public class InstallersPage extends Control implements WizardPage {
if (!(library.resolvedStateProperty().get() instanceof InstallerItem.IncompatibleState))
controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false)));
});
library.removeActionProperty().set(e -> {
library.setOnRemove(() -> {
controller.getSettings().remove(libraryId);
reload();
});
@@ -222,7 +222,7 @@ public class InstallersPage extends Control implements WizardPage {
installButton.disableProperty().bind(control.installable.not());
installButton.setPrefWidth(100);
installButton.setPrefHeight(40);
installButton.setOnMouseClicked(e -> control.onInstall());
installButton.setOnAction(e -> control.onInstall());
BorderPane.setAlignment(installButton, Pos.CENTER_RIGHT);
root.setBottom(installButton);
}
@@ -95,7 +95,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
HintPane hintPane = new HintPane();
hintPane.setText(i18n("sponsor.bmclapi"));
hintPane.getStyleClass().add("sponsor-pane");
hintPane.setOnMouseClicked(e -> onSponsor());
FXUtils.onClicked(hintPane, this::onSponsor);
BorderPane.setMargin(hintPane, new Insets(10, 10, 0, 10));
this.setTop(hintPane);
@@ -146,7 +146,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
failedPane.getStyleClass().add("notice-pane");
{
Label label = new Label(i18n("download.failed.refresh"));
label.setOnMouseClicked(e -> onRefresh());
FXUtils.onClicked(label, this::onRefresh);
failedPane.getChildren().setAll(label);
}
@@ -155,7 +155,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
emptyPane.getStyleClass().add("notice-pane");
{
Label label = new Label(i18n("download.failed.empty"));
label.setOnMouseClicked(e -> onBack());
FXUtils.onClicked(label, this::onBack);
emptyPane.getChildren().setAll(label);
}
@@ -180,7 +180,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
Holder<RemoteVersionListCell> lastCell = new Holder<>();
list.setCellFactory(listView -> new RemoteVersionListCell(lastCell));
list.setOnMouseClicked(e -> {
FXUtils.onClicked(list, () -> {
if (list.getSelectionModel().getSelectedIndex() < 0)
return;
navigation.getSettings().put(libraryId, list.getSelectionModel().getSelectedItem());
@@ -210,7 +210,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
@Override
public void refresh() {
VersionList<?> currentVersionList = versionList;
root.setContent(spinner, ContainerAnimations.FADE.getAnimationProducer());
root.setContent(spinner, ContainerAnimations.FADE);
executor = currentVersionList.refreshAsync(gameVersion).whenComplete((result, exception) -> {
if (exception == null) {
List<RemoteVersion> items = loadVersions();
@@ -218,7 +218,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
Platform.runLater(() -> {
if (versionList != currentVersionList) return;
if (currentVersionList.getVersions(gameVersion).isEmpty()) {
root.setContent(emptyPane, ContainerAnimations.FADE.getAnimationProducer());
root.setContent(emptyPane, ContainerAnimations.FADE);
} else {
if (items.isEmpty()) {
chkRelease.setSelected(true);
@@ -227,14 +227,14 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
} else {
list.getItems().setAll(items);
}
root.setContent(center, ContainerAnimations.FADE.getAnimationProducer());
root.setContent(center, ContainerAnimations.FADE);
}
});
} else {
LOG.warning("Failed to fetch versions list", exception);
Platform.runLater(() -> {
if (versionList != currentVersionList) return;
root.setContent(failedPane, ContainerAnimations.FADE.getAnimationProducer());
root.setContent(failedPane, ContainerAnimations.FADE);
});
}
@@ -21,12 +21,10 @@ import com.jfoenix.controls.*;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.auth.Account;
@@ -78,7 +76,6 @@ public final class ModpackInfoPage extends Control implements WizardPage {
private final SimpleStringProperty authlibInjectorServer = new SimpleStringProperty();
private final SimpleStringProperty launchArguments = new SimpleStringProperty("");
private final SimpleStringProperty javaArguments = new SimpleStringProperty("");
private final ObjectProperty<EventHandler<? super MouseEvent>> next = new SimpleObjectProperty<>();
private final SimpleStringProperty mcbbsThreadId = new SimpleStringProperty("");
public ModpackInfoPage(WizardController controller, HMCLGameRepository gameRepository, String version) {
@@ -97,8 +94,6 @@ public final class ModpackInfoPage extends Control implements WizardPage {
javaArguments.set(versionSetting.getJavaArgs());
canIncludeLauncher = JarUtils.thisJarPath() != null;
next.set(e -> onNext());
}
private void onNext() {
@@ -178,9 +173,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
if (skinnable.controller.getSettings().get(MODPACK_TYPE) == MODPACK_TYPE_SERVER) {
Hyperlink hyperlink = new Hyperlink(i18n("modpack.wizard.step.initialization.server"));
hyperlink.setOnMouseClicked(e -> {
FXUtils.openLink("https://docs.hmcl.net/modpack/serverpack.html");
});
hyperlink.setOnAction(e -> FXUtils.openLink("https://docs.hmcl.net/modpack/serverpack.html"));
borderPane.setTop(hyperlink);
} else {
HintPane pane = new HintPane(MessageDialogPane.MessageType.INFO);
@@ -378,7 +371,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
borderPane.setBottom(hbox);
JFXButton nextButton = FXUtils.newRaisedButton(i18n("wizard.next"));
nextButton.onMouseClickedProperty().bind(skinnable.next);
nextButton.setOnAction(e -> skinnable.onNext());
nextButton.setPrefWidth(100);
nextButton.setPrefHeight(40);
nextButton.disableProperty().bind(
@@ -36,7 +36,6 @@ import org.jackhuang.hmcl.ui.versions.VersionSettingsPage;
import java.util.Locale;
import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class LauncherSettingsPage extends DecoratorAnimatedPage implements DecoratorPage, PageAware {
@@ -67,7 +66,7 @@ public class LauncherSettingsPage extends DecoratorAnimatedPage implements Decor
gameTab.initializeIfNeeded();
gameTab.getNode().loadVersion(Profiles.getSelectedProfile(), null);
FXUtils.onChangeAndOperate(tab.getSelectionModel().selectedItemProperty(), newValue -> {
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE);
});
{
@@ -76,7 +75,6 @@ public class LauncherSettingsPage extends DecoratorAnimatedPage implements Decor
settingsItem.setTitle(i18n("settings.type.global.manage"));
settingsItem.setLeftGraphic(wrap(SVG.GAMEPAD));
settingsItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(gameTab));
runInFX(() -> FXUtils.installFastTooltip(settingsItem, i18n("settings.type.global.manage")));
settingsItem.setOnAction(e -> tab.select(gameTab));
})
.addNavigationDrawerItem(javaItem -> {
@@ -32,7 +32,6 @@ import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
@@ -46,6 +45,8 @@ import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
import org.jackhuang.hmcl.ui.animation.TransitionPane;
import org.jackhuang.hmcl.ui.construct.AnnouncementCard;
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
import org.jackhuang.hmcl.ui.construct.PopupMenu;
@@ -65,7 +66,6 @@ import java.util.stream.IntStream;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.SINE;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class MainPage extends StackPane implements DecoratorPage {
@@ -83,7 +83,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
private final ObservableList<Node> versionNodes;
private Profile profile;
private VBox announcementPane;
private TransitionPane announcementPane;
private final StackPane updatePane;
private final JFXButton menuButton;
@@ -102,13 +102,23 @@ public final class MainPage extends StackPane implements DecoratorPage {
setPadding(new Insets(20));
if (Metadata.isNightly() || (Metadata.isDev() && !Objects.equals(Metadata.VERSION, config().getShownTips().get(ANNOUNCEMENT)))) {
announcementPane = new VBox(16);
AnnouncementCard announcementCard = null;
if (Metadata.isNightly()) {
announcementPane.getChildren().add(new AnnouncementCard(i18n("update.channel.nightly.title"), i18n("update.channel.nightly.hint")));
announcementCard = new AnnouncementCard(i18n("update.channel.nightly.title"), i18n("update.channel.nightly.hint"), null);
} else if (Metadata.isDev()) {
announcementPane.getChildren().add(new AnnouncementCard(i18n("update.channel.dev.title"), i18n("update.channel.dev.hint")));
announcementCard = new AnnouncementCard(i18n("update.channel.dev.title"), i18n("update.channel.dev.hint"), this::hideAnnouncementPane);
}
if (announcementCard != null) {
VBox announcementBox = new VBox(16);
announcementBox.getChildren().add(announcementCard);
announcementPane = new TransitionPane();
announcementPane.setContent(announcementBox, ContainerAnimations.NONE);
getChildren().add(announcementPane);
}
getChildren().add(announcementPane);
}
updatePane = new StackPane();
@@ -117,7 +127,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
FXUtils.setLimitWidth(updatePane, 230);
FXUtils.setLimitHeight(updatePane, 55);
StackPane.setAlignment(updatePane, Pos.TOP_RIGHT);
updatePane.setOnMouseClicked(e -> onUpgrade());
FXUtils.onClicked(updatePane, this::onUpgrade);
FXUtils.onChange(showUpdateProperty(), this::showUpdate);
{
@@ -144,7 +154,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
StackPane.setAlignment(closeUpdateButton, Pos.TOP_RIGHT);
closeUpdateButton.getStyleClass().add("toggle-icon-tiny");
StackPane.setMargin(closeUpdateButton, new Insets(5));
closeUpdateButton.setOnMouseClicked(e -> closeUpdateBubble());
closeUpdateButton.setOnAction(e -> closeUpdateBubble());
updatePane.getChildren().setAll(hBox, closeUpdateButton);
}
@@ -206,14 +216,14 @@ public final class MainPage extends StackPane implements DecoratorPage {
menuButton.setPrefWidth(230);
//menuButton.setButtonType(JFXButton.ButtonType.RAISED);
menuButton.setStyle("-fx-font-size: 15px;");
menuButton.setOnMouseClicked(e -> onMenu());
menuButton.setOnAction(e -> onMenu());
menuButton.setClip(new Rectangle(211, -100, 100, 200));
StackPane graphic = new StackPane();
Node svg = SVG.TRIANGLE.createIcon(Theme.foregroundFillBinding(), 10, 10);
StackPane.setAlignment(svg, Pos.CENTER_RIGHT);
graphic.getChildren().setAll(svg);
graphic.setTranslateX(12);
runInFX(() -> FXUtils.installFastTooltip(menuButton, i18n("version.switch")));
FXUtils.installFastTooltip(menuButton, i18n("version.switch"));
menuButton.setGraphic(graphic);
launchPane.getChildren().setAll(launchButton, separator, menuButton);
@@ -224,10 +234,10 @@ public final class MainPage extends StackPane implements DecoratorPage {
menu.setMaxHeight(365);
menu.setMaxWidth(545);
menu.setAlwaysShowingVBar(true);
menu.setOnMouseClicked(e -> popup.hide());
FXUtils.onClicked(menu, popup::hide);
versionNodes = MappedObservableList.create(versions, version -> {
Node node = PopupMenu.wrapPopupMenuItem(new GameItem(profile, version.getId()));
node.setOnMouseClicked(e -> profile.setSelectedVersion(version.getId()));
FXUtils.onClicked(node, () -> profile.setSelectedVersion(version.getId()));
return node;
});
Bindings.bindContent(menu.getContent(), versionNodes);
@@ -290,10 +300,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
public void hideAnnouncementPane() {
if (announcementPane != null) {
config().getShownTips().put(ANNOUNCEMENT, Metadata.VERSION);
Pane parent = (Pane) announcementPane.getParent();
if (parent != null)
parent.getChildren().remove(announcementPane);
announcementPane = null;
announcementPane.setContent(new StackPane(), ContainerAnimations.FADE);
}
}
@@ -165,7 +165,7 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
downloadItem.setActionButtonVisible(false);
downloadItem.setTitle(i18n("download"));
downloadItem.setOnAction(e -> Controllers.navigate(Controllers.getDownloadPage()));
runInFX(() -> FXUtils.installFastTooltip(downloadItem, i18n("download.hint")));
FXUtils.installFastTooltip(downloadItem, i18n("download.hint"));
// fifth item in left sidebar
AdvancedListItem launcherSettingsItem = new AdvancedListItem();
@@ -73,7 +73,7 @@ public abstract class SettingsView extends StackPane {
{
StackPane sponsorPane = new StackPane();
sponsorPane.setCursor(Cursor.HAND);
sponsorPane.setOnMouseClicked(e -> onSponsor());
FXUtils.onClicked(sponsorPane, this::onSponsor);
sponsorPane.setPadding(new Insets(8, 0, 8, 0));
GridPane gridPane = new GridPane();
@@ -121,7 +121,7 @@ public abstract class SettingsView extends StackPane {
{
btnUpdate = new JFXButton();
btnUpdate.setOnMouseClicked(e -> onUpdate());
btnUpdate.setOnAction(e -> onUpdate());
btnUpdate.getStyleClass().add("toggle-icon4");
btnUpdate.setGraphic(SVG.UPDATE.createIcon(Theme.blackFill(), 20, 20));
@@ -161,7 +161,7 @@ public abstract class SettingsView extends StackPane {
{
JFXButton cleanButton = new JFXButton(i18n("launcher.cache_directory.clean"));
cleanButton.setOnMouseClicked(e -> clearCacheDirectory());
cleanButton.setOnAction(e -> clearCacheDirectory());
cleanButton.getStyleClass().add("jfx-button-border");
fileCommonLocationSublist.setHeaderRight(cleanButton);
@@ -193,11 +193,11 @@ public abstract class SettingsView extends StackPane {
debugPane.setLeft(left);
JFXButton openLogFolderButton = new JFXButton(i18n("settings.launcher.launcher_log.reveal"));
openLogFolderButton.setOnMouseClicked(e -> openLogFolder());
openLogFolderButton.setOnAction(e -> openLogFolder());
openLogFolderButton.getStyleClass().add("jfx-button-border");
JFXButton logButton = new JFXButton(i18n("settings.launcher.launcher_log.export"));
logButton.setOnMouseClicked(e -> onExportLogs());
logButton.setOnAction(e -> onExportLogs());
logButton.getStyleClass().add("jfx-button-border");
HBox buttonBox = new HBox();
@@ -22,7 +22,6 @@ import javafx.css.PseudoClass;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.SkinBase;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import org.jackhuang.hmcl.setting.Theme;
@@ -47,9 +46,7 @@ public class ProfileListItemSkin extends SkinBase<ProfileListItem> {
skinnable.pseudoClassStateChanged(SELECTED, active);
});
getSkinnable().addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
getSkinnable().setSelected(true);
});
FXUtils.onClicked(getSkinnable(), () -> getSkinnable().setSelected(true));
Node left = VersionPage.wrap(SVG.FOLDER_OUTLINE);
root.setLeft(left);
@@ -64,7 +61,7 @@ public class ProfileListItemSkin extends SkinBase<ProfileListItem> {
right.setAlignment(Pos.CENTER_RIGHT);
JFXButton btnRemove = new JFXButton();
btnRemove.setOnMouseClicked(e -> skinnable.remove());
btnRemove.setOnAction(e -> skinnable.remove());
btnRemove.getStyleClass().add("toggle-icon4");
BorderPane.setAlignment(btnRemove, Pos.CENTER);
btnRemove.setGraphic(SVG.CLOSE.createIcon(Theme.blackFill(), 14, 14));
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.event.Event;
import javafx.event.EventHandler;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.animation.AnimationTimer;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.scene.*;
import javafx.scene.image.Image;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.scene.shape.Mesh;
import javafx.scene.shape.MeshView;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.scene.Group;
import javafx.scene.Node;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.scene.image.Image;
import javafx.scene.image.PixelReader;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.geometry.Point2D;
import javafx.scene.Group;
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.animation.Transition;
import javafx.beans.value.WritableValue;
@@ -1,10 +1,10 @@
package moe.mickey.minecraft.skin.fx.animation;
package org.jackhuang.hmcl.ui.skin.animation;
import javafx.util.Duration;
import moe.mickey.minecraft.skin.fx.FunctionHelper;
import moe.mickey.minecraft.skin.fx.SkinAnimation;
import moe.mickey.minecraft.skin.fx.SkinCanvas;
import moe.mickey.minecraft.skin.fx.SkinTransition;
import org.jackhuang.hmcl.ui.skin.FunctionHelper;
import org.jackhuang.hmcl.ui.skin.SkinAnimation;
import org.jackhuang.hmcl.ui.skin.SkinCanvas;
import org.jackhuang.hmcl.ui.skin.SkinTransition;
public final class SkinAniRunning extends SkinAnimation {
@@ -1,10 +1,10 @@
package moe.mickey.minecraft.skin.fx.animation;
package org.jackhuang.hmcl.ui.skin.animation;
import javafx.util.Duration;
import moe.mickey.minecraft.skin.fx.FunctionHelper;
import moe.mickey.minecraft.skin.fx.SkinAnimation;
import moe.mickey.minecraft.skin.fx.SkinCanvas;
import moe.mickey.minecraft.skin.fx.SkinTransition;
import org.jackhuang.hmcl.ui.skin.FunctionHelper;
import org.jackhuang.hmcl.ui.skin.SkinAnimation;
import org.jackhuang.hmcl.ui.skin.SkinCanvas;
import org.jackhuang.hmcl.ui.skin.SkinTransition;
public final class SkinAniWavingArms extends SkinAnimation {
@@ -64,7 +64,6 @@ import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor;
@@ -302,7 +301,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
lblGameVersion.visibleProperty().bind(hasVersion);
gameVersionField.managedProperty().bind(hasVersion);
gameVersionField.visibleProperty().bind(hasVersion);
runInFX(() -> FXUtils.installFastTooltip(gameVersionField, i18n("search.enter")));
FXUtils.installFastTooltip(gameVersionField, i18n("search.enter"));
FXUtils.onChangeAndOperate(getSkinnable().version, version -> {
if (StringUtils.isNotBlank(version.getVersion())) {
@@ -488,7 +487,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
JFXListView<RemoteMod> listView = new JFXListView<>();
spinnerPane.setContent(listView);
Bindings.bindContent(listView.getItems(), getSkinnable().items);
listView.setOnMouseClicked(e -> {
FXUtils.onClicked(listView, () -> {
if (listView.getSelectionModel().getSelectedIndex() < 0)
return;
RemoteMod selectedItem = listView.getSelectionModel().getSelectedItem();
@@ -62,7 +62,6 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class DownloadPage extends Control implements DecoratorPage {
@@ -241,14 +240,14 @@ public class DownloadPage extends Control implements DecoratorPage {
openMcmodButton.setExternalLink(getSkinnable().translations.getMcmodUrl(getSkinnable().mod));
descriptionPane.getChildren().add(openMcmodButton);
openMcmodButton.setMinWidth(Region.USE_PREF_SIZE);
runInFX(() -> FXUtils.installFastTooltip(openMcmodButton, i18n("mods.mcmod")));
FXUtils.installFastTooltip(openMcmodButton, i18n("mods.mcmod"));
}
JFXHyperlink openUrlButton = new JFXHyperlink(control.page.getLocalizedOfficialPage());
openUrlButton.setExternalLink(getSkinnable().addon.getPageUrl());
descriptionPane.getChildren().add(openUrlButton);
openUrlButton.setMinWidth(Region.USE_PREF_SIZE);
runInFX(() -> FXUtils.installFastTooltip(openUrlButton, control.page.getLocalizedOfficialPage()));
FXUtils.installFastTooltip(openUrlButton, control.page.getLocalizedOfficialPage());
}
SpinnerPane spinnerPane = new SpinnerPane();
@@ -346,7 +345,10 @@ public class DownloadPage extends Control implements DecoratorPage {
pane.getChildren().setAll(FXUtils.limitingSize(imageView, 40, 40), content);
RipplerContainer container = new RipplerContainer(pane);
container.setOnMouseClicked(e -> Controllers.navigate(new DownloadPage(page, addon, version, callback)));
FXUtils.onClicked(container, () -> {
fireEvent(new DialogCloseEvent());
Controllers.navigate(new DownloadPage(page, addon, version, callback));
});
getChildren().setAll(container);
if (addon != RemoteMod.BROKEN) {
@@ -428,7 +430,7 @@ public class DownloadPage extends Control implements DecoratorPage {
}
RipplerContainer container = new RipplerContainer(pane);
container.setOnMouseClicked(e -> Controllers.dialog(new ModVersion(dataItem, selfPage)));
FXUtils.onClicked(container, () -> Controllers.dialog(new ModVersion(dataItem, selfPage)));
getChildren().setAll(container);
// Workaround for https://github.com/HMCL-dev/HMCL/issues/2129
@@ -443,7 +445,7 @@ public class DownloadPage extends Control implements DecoratorPage {
VBox box = new VBox(8);
box.setPadding(new Insets(8));
ModItem modItem = new ModItem(version, selfPage);
modItem.setOnMouseClicked(e -> fireEvent(new DialogCloseEvent()));
FXUtils.onClicked(modItem, () -> fireEvent(new DialogCloseEvent()));
box.getChildren().setAll(modItem);
SpinnerPane spinnerPane = new SpinnerPane();
ScrollPane scrollPane = new ScrollPane();
@@ -505,7 +507,6 @@ public class DownloadPage extends Control implements DecoratorPage {
dependencies.put(dependency.getType(), list);
}
DependencyModItem dependencyModItem = new DependencyModItem(selfPage.page, dependency.load(), selfPage.version, selfPage.callback);
dependencyModItem.setOnMouseClicked(e -> fireEvent(new DialogCloseEvent()));
dependencies.get(dependency.getType()).add(dependencyModItem);
}
@@ -18,7 +18,6 @@
package org.jackhuang.hmcl.ui.versions;
import javafx.scene.Node;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import org.jackhuang.hmcl.event.Event;
import org.jackhuang.hmcl.setting.Profile;
@@ -34,15 +33,13 @@ import java.util.function.Consumer;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class GameAdvancedListItem extends AdvancedListItem {
private final Tooltip tooltip;
private final ImageView imageView;
private final WeakListenerHolder holder = new WeakListenerHolder();
private Profile profile;
@SuppressWarnings("unused")
private Consumer<Event> onVersionIconChangedListener;
public GameAdvancedListItem() {
tooltip = new Tooltip();
Pair<Node, ImageView> view = createImageView(null);
setLeftGraphic(view.getKey());
imageView = view.getValue();
@@ -63,17 +60,13 @@ public class GameAdvancedListItem extends AdvancedListItem {
}
if (version != null && Profiles.getSelectedProfile() != null &&
Profiles.getSelectedProfile().getRepository().hasVersion(version)) {
FXUtils.installFastTooltip(this, tooltip);
setTitle(version);
setSubtitle(null);
setTitle(i18n("version.manage.manage"));
setSubtitle(version);
imageView.setImage(Profiles.getSelectedProfile().getRepository().getVersionIconImage(version));
tooltip.setText(version);
} else {
Tooltip.uninstall(this,tooltip);
setTitle(i18n("version.empty"));
setSubtitle(i18n("version.empty.add"));
imageView.setImage(VersionIconType.DEFAULT.getIcon());
tooltip.setText("");
}
}
}
@@ -35,7 +35,6 @@ import org.jackhuang.hmcl.ui.construct.PopupMenu;
import org.jackhuang.hmcl.ui.construct.RipplerContainer;
import org.jackhuang.hmcl.util.Lazy;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class GameListItemSkin extends SkinBase<GameListItem> {
@@ -79,33 +78,33 @@ public class GameListItemSkin extends SkinBase<GameListItem> {
right.setAlignment(Pos.CENTER_RIGHT);
if (skinnable.canUpdate()) {
JFXButton btnUpgrade = new JFXButton();
btnUpgrade.setOnMouseClicked(e -> skinnable.update());
btnUpgrade.setOnAction(e -> skinnable.update());
btnUpgrade.getStyleClass().add("toggle-icon4");
btnUpgrade.setGraphic(FXUtils.limitingSize(SVG.UPDATE.createIcon(Theme.blackFill(), 24, 24), 24, 24));
runInFX(() -> FXUtils.installFastTooltip(btnUpgrade, i18n("version.update")));
FXUtils.installFastTooltip(btnUpgrade, i18n("version.update"));
right.getChildren().add(btnUpgrade);
}
{
JFXButton btnLaunch = new JFXButton();
btnLaunch.setOnMouseClicked(e -> skinnable.launch());
btnLaunch.setOnAction(e -> skinnable.launch());
btnLaunch.getStyleClass().add("toggle-icon4");
BorderPane.setAlignment(btnLaunch, Pos.CENTER);
btnLaunch.setGraphic(FXUtils.limitingSize(SVG.ROCKET_LAUNCH_OUTLINE.createIcon(Theme.blackFill(), 24, 24), 24, 24));
runInFX(() -> FXUtils.installFastTooltip(btnLaunch, i18n("version.launch.test")));
FXUtils.installFastTooltip(btnLaunch, i18n("version.launch.test"));
right.getChildren().add(btnLaunch);
}
{
JFXButton btnManage = new JFXButton();
btnManage.setOnMouseClicked(e -> {
btnManage.setOnAction(e -> {
currentSkinnable = skinnable;
popup.get().show(root, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, root.getHeight());
});
btnManage.getStyleClass().add("toggle-icon4");
BorderPane.setAlignment(btnManage, Pos.CENTER);
btnManage.setGraphic(FXUtils.limitingSize(SVG.DOTS_VERTICAL.createIcon(Theme.blackFill(), 24, 24), 24, 24));
runInFX(() -> FXUtils.installFastTooltip(btnManage, i18n("settings.game.management")));
FXUtils.installFastTooltip(btnManage, i18n("settings.game.management"));
right.getChildren().add(btnManage);
}
@@ -91,13 +91,11 @@ public class GameListPage extends DecoratorAnimatedPage implements DecoratorPage
installNewGameItem.setTitle(i18n("install.new_game"));
installNewGameItem.setLeftGraphic(VersionPage.wrap(SVG.PLUS_CIRCLE_OUTLINE));
installNewGameItem.setOnAction(e -> Versions.addNewGame());
runInFX(() -> FXUtils.installFastTooltip(installNewGameItem, i18n("install.new_game")));
})
.addNavigationDrawerItem(installModpackItem -> {
installModpackItem.setTitle(i18n("install.modpack"));
installModpackItem.setLeftGraphic(VersionPage.wrap(SVG.PACK));
installModpackItem.setOnAction(e -> Versions.importModpack());
runInFX(() -> FXUtils.installFastTooltip(installModpackItem, i18n("install.modpack")));
})
.addNavigationDrawerItem(refreshItem -> {
refreshItem.setTitle(i18n("button.refresh"));
@@ -108,7 +106,6 @@ public class GameListPage extends DecoratorAnimatedPage implements DecoratorPage
globalManageItem.setTitle(i18n("settings.type.global.manage"));
globalManageItem.setLeftGraphic(VersionPage.wrap(SVG.GEAR_OUTLINE));
globalManageItem.setOnAction(e -> modifyGlobalGameSettings());
runInFX(() -> FXUtils.installFastTooltip(globalManageItem, i18n("settings.type.global.manage")));
});
FXUtils.setLimitHeight(bottomLeftCornerList, 40 * 4 + 12 * 2);
setLeft(pane, bottomLeftCornerList);
@@ -97,11 +97,11 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
item.versionProperty().set(null);
}
item.installActionProperty().set(e -> {
item.setOnInstall(() -> {
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
});
item.removeActionProperty().set(e -> profile.getDependency().removeLibraryAsync(version, libraryId)
item.setOnRemove(() -> profile.getDependency().removeLibraryAsync(version, libraryId)
.thenComposeAsync(profile.getRepository()::saveAsync)
.withComposeAsync(profile.getRepository().refreshVersionsAsync())
.withRunAsync(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId))
@@ -121,7 +121,7 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
InstallerItem installerItem = new InstallerItem(libraryId, InstallerItem.Style.LIST_ITEM);
installerItem.versionProperty().set(new InstallerItem.InstalledState(libraryVersion, false, false));
installerItem.removeActionProperty().set(e -> profile.getDependency().removeLibraryAsync(version, libraryId)
installerItem.setOnRemove(() -> profile.getDependency().removeLibraryAsync(version, libraryId)
.thenComposeAsync(profile.getRepository()::saveAsync)
.withComposeAsync(profile.getRepository().refreshVersionsAsync())
.withRunAsync(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId))
@@ -186,6 +186,14 @@ class ModListPageSkin extends SkinBase<ModListPage> {
}
});
listView.setOnContextMenuRequested(event -> {
ModInfoObject selectedItem = listView.getSelectionModel().getSelectedItem();
if (selectedItem != null && listView.getSelectionModel().getSelectedItems().size() == 1) {
listView.getSelectionModel().clearSelection();
Controllers.dialog(new ModInfoDialog(selectedItem));
}
});
center.setContent(listView);
root.getContent().add(center);
}
@@ -204,7 +212,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
private void changeToolbar(HBox newToolbar) {
Node oldToolbar = toolbarPane.getCurrentNode();
if (newToolbar != oldToolbar) {
toolbarPane.setContent(newToolbar, ContainerAnimations.FADE.getAnimationProducer());
toolbarPane.setContent(newToolbar, ContainerAnimations.FADE);
if (newToolbar == searchBar) {
searchField.requestFocus();
}
@@ -539,7 +547,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
}
checkBox.selectedProperty().bindBidirectional(booleanProperty = dataItem.active);
restoreButton.setVisible(!dataItem.getModInfo().getMod().getOldFiles().isEmpty());
restoreButton.setOnMouseClicked(e -> {
restoreButton.setOnAction(e -> {
menu.get().getContent().setAll(dataItem.getModInfo().getMod().getOldFiles().stream()
.map(localModFile -> new IconedMenuItem(null, localModFile.getVersion(),
() -> getSkinnable().rollback(dataItem.getModInfo(), localModFile),
@@ -549,12 +557,8 @@ class ModListPageSkin extends SkinBase<ModListPage> {
popup.get().show(restoreButton, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, restoreButton.getHeight());
});
revealButton.setOnMouseClicked(e -> {
FXUtils.showFileInExplorer(dataItem.getModInfo().getFile());
});
infoButton.setOnMouseClicked(e -> {
Controllers.dialog(new ModInfoDialog(dataItem));
});
revealButton.setOnAction(e -> FXUtils.showFileInExplorer(dataItem.getModInfo().getFile()));
infoButton.setOnAction(e -> Controllers.dialog(new ModInfoDialog(dataItem)));
}
}
}
@@ -95,9 +95,7 @@ public class VersionIconDialog extends DialogPane {
RipplerContainer container = new RipplerContainer(shape);
FXUtils.setLimitWidth(container, 36);
FXUtils.setLimitHeight(container, 36);
container.setOnMouseClicked(e -> {
exploreIcon();
});
FXUtils.onClicked(container, this::exploreIcon);
return container;
}
@@ -107,7 +105,7 @@ public class VersionIconDialog extends DialogPane {
RipplerContainer container = new RipplerContainer(imageView);
FXUtils.setLimitWidth(container, 36);
FXUtils.setLimitHeight(container, 36);
container.setOnMouseClicked(e -> {
FXUtils.onClicked(container, () -> {
if (vs != null) {
vs.setVersionIcon(type);
onAccept();
@@ -78,7 +78,7 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
tab.select(versionSettingsTab);
FXUtils.onChangeAndOperate(tab.getSelectionModel().selectedItemProperty(), newValue -> {
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE);
});
listenerHolder.add(EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerWeak(event -> checkSelectedVersion(), EventPriority.HIGHEST));
@@ -244,7 +244,6 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
versionSettingsItem.setLeftGraphic(wrap(SVG.GEAR_OUTLINE));
versionSettingsItem.setActionButtonVisible(false);
versionSettingsItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.versionSettingsTab));
runInFX(() -> FXUtils.installFastTooltip(versionSettingsItem, i18n("settings.game")));
versionSettingsItem.setOnAction(e -> control.tab.select(control.versionSettingsTab));
AdvancedListItem installerListItem = new AdvancedListItem();
@@ -253,7 +252,6 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
installerListItem.setLeftGraphic(wrap(SVG.CUBE));
installerListItem.setActionButtonVisible(false);
installerListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.installerListTab));
runInFX(() -> FXUtils.installFastTooltip(installerListItem, i18n("settings.tabs.installers")));
installerListItem.setOnAction(e -> control.tab.select(control.installerListTab));
AdvancedListItem modListItem = new AdvancedListItem();
@@ -262,7 +260,6 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
modListItem.setLeftGraphic(wrap(SVG.PUZZLE));
modListItem.setActionButtonVisible(false);
modListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.modListTab));
runInFX(() -> FXUtils.installFastTooltip(modListItem, i18n("mods.manage")));
modListItem.setOnAction(e -> control.tab.select(control.modListTab));
AdvancedListItem worldListItem = new AdvancedListItem();
@@ -271,7 +268,6 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
worldListItem.setLeftGraphic(wrap(SVG.EARTH));
worldListItem.setActionButtonVisible(false);
worldListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.worldListTab));
runInFX(() -> FXUtils.installFastTooltip(worldListItem, i18n("world.manage")));
worldListItem.setOnAction(e -> control.tab.select(control.worldListTab));
AdvancedListBox sideBar = new AdvancedListBox()
@@ -685,7 +685,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
version = null;
} else {
gameVersionNumber = GameVersionNumber.asGameVersion(repository.getGameVersion(versionId));
version = repository.getVersion(versionId);
version = repository.getResolvedVersion(versionId);
}
try {
@@ -83,7 +83,7 @@ public class WorldExportPageSkin extends SkinBase<WorldExportPage> {
JFXButton btnExport = FXUtils.newRaisedButton(i18n("button.export"));
btnExport.disableProperty().bind(Bindings.createBooleanBinding(() -> txtWorldName.getText().isEmpty() || Files.exists(Paths.get(fileItem.getPath())),
txtWorldName.textProperty().isEmpty(), fileItem.pathProperty()));
btnExport.setOnMouseClicked(e -> skinnable.export());
btnExport.setOnAction(e -> skinnable.export());
HBox bottom = new HBox();
bottom.setAlignment(Pos.CENTER_RIGHT);
bottom.getChildren().setAll(btnExport);
@@ -51,7 +51,7 @@ public class WorldListItem extends Control {
subtitle.set(i18n("world.description", world.getFileName(), formatDateTime(Instant.ofEpochMilli(world.getLastPlayed())), world.getGameVersion() == null ? i18n("message.unknown") : world.getGameVersion()));
setOnMouseClicked(event -> showInfo());
FXUtils.onClicked(this, this::showInfo);
}
@Override
@@ -76,9 +76,7 @@ public class WorldListItemSkin extends SkinBase<WorldListItem> {
right.setAlignment(Pos.CENTER_RIGHT);
JFXButton btnManage = new JFXButton();
btnManage.setOnMouseClicked(e -> {
popup.show(root, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, root.getHeight());
});
btnManage.setOnAction(e -> popup.show(root, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, root.getHeight()));
btnManage.getStyleClass().add("toggle-icon4");
BorderPane.setAlignment(btnManage, Pos.CENTER);
btnManage.setGraphic(SVG.DOTS_VERTICAL.createIcon(Theme.blackFill(), -1, -1));
@@ -39,16 +39,6 @@ public final class Locales {
*/
public static final SupportedLocale EN = new SupportedLocale(Locale.ROOT);
/**
* Traditional Chinese
*/
public static final SupportedLocale ZH = new SupportedLocale(Locale.TRADITIONAL_CHINESE);
/**
* Simplified Chinese
*/
public static final SupportedLocale ZH_CN = new SupportedLocale(Locale.SIMPLIFIED_CHINESE);
/**
* Spanish
*/
@@ -64,23 +54,33 @@ public final class Locales {
*/
public static final SupportedLocale JA = new SupportedLocale(Locale.JAPANESE);
public static final List<SupportedLocale> LOCALES = Lang.immutableListOf(DEFAULT, EN, ZH_CN, ZH, ES, RU, JA);
/**
* Traditional Chinese
*/
public static final SupportedLocale ZH = new SupportedLocale(Locale.TRADITIONAL_CHINESE);
/**
* Simplified Chinese
*/
public static final SupportedLocale ZH_CN = new SupportedLocale(Locale.SIMPLIFIED_CHINESE);
public static final List<SupportedLocale> LOCALES = Lang.immutableListOf(DEFAULT, EN, ES, JA, RU, ZH_CN, ZH);
public static SupportedLocale getLocaleByName(String name) {
if (name == null) return DEFAULT;
switch (name.toLowerCase(Locale.ROOT)) {
case "en":
return EN;
case "es":
return ES;
case "ja":
return JA;
case "ru":
return RU;
case "zh":
return ZH;
case "zh_cn":
return ZH_CN;
case "es":
return ES;
case "ru":
return RU;
case "ja":
return JA;
default:
return DEFAULT;
}
@@ -88,11 +88,11 @@ public final class Locales {
public static String getNameByLocale(SupportedLocale locale) {
if (locale == EN) return "en";
else if (locale == ZH) return "zh";
else if (locale == ZH_CN) return "zh_CN";
else if (locale == ES) return "es";
else if (locale == RU) return "ru";
else if (locale == JA) return "ja";
else if (locale == ZH) return "zh";
else if (locale == ZH_CN) return "zh_CN";
else if (locale == DEFAULT) return "def";
else throw new IllegalArgumentException("Unknown locale: " + locale);
}
Binary file not shown.
@@ -24,5 +24,8 @@
-fx-base-disabled-text-fill: rgba(256, 256, 256, 0.7);
-fx-base-text-fill: white;
/* https://github.com/HMCL-dev/HMCL/pull/3423 */
-fx-font-family: -fx-base-font-family;
-theme-thumb: rgba(92, 107, 192, 0.7);
}
@@ -1,30 +0,0 @@
/**
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> 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 <https://www.gnu.org/licenses/>.
*/
.root {
-fx-base-color: %base-color%;
-fx-base-darker-color: derive(-fx-base-color, -10%);
-fx-base-check-color: derive(-fx-base-color, 30%);
-fx-rippler-color: rgba(%base-red%, %base-green%, %base-blue%, 0.3);
-fx-base-rippler-color: derive(%base-rippler-color%, 100%);
-fx-base-disabled-text-fill: %disabled-font-color%;
-fx-base-text-fill: %font-color%;
-theme-thumb: rgba(%base-red%, %base-green%, %base-blue%, 0.7);
%font%
}
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2023 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2024 huangyuhui <huanghongxun2008@126.com> 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
@@ -29,16 +29,16 @@ about.claim.statement=Click this link for full text.
about.dependency=Third-party Libraries
about.legal=Legal Acknowledgement
about.thanks_to=Thanks to
about.thanks_to.bangbang93.statement=For providing the BMCLAPI download mirror, please consider donating!
about.thanks_to.bangbang93.statement=For providing the BMCLAPI download mirror. Please consider donating!
about.thanks_to.burningtnt.statement=Contribute a lot of technical support to HMCL.
about.thanks_to.contributors=All contributors on GitHub
about.thanks_to.contributors.statement=Without the awesome open-source community, HMCL would not make it so far.
about.thanks_to.contributors.statement=Without the awesome open-source community, HMCL would not have made it so far.
about.thanks_to.gamerteam.statement=For providing the default background image.
about.thanks_to.glavo.statement=Responsible for maintaining HMCL.
about.thanks_to.zekerzhayard.statement=Contribute a lot of technical support to HMCL.
about.thanks_to.zkitefly.statement=Responsible for maintaining the documentation of HMCL.
about.thanks_to.mcbbs=MCBBS (Minecraft Chinese Forum)
about.thanks_to.mcbbs.statement=For providing the mcbbs.net download mirror for Chinese Mainland users.
about.thanks_to.mcbbs.statement=For providing the mcbbs.net download mirror for Chinese Mainland users. (No longer available)
about.thanks_to.mcmod=MCMod (mcmod.cn)
about.thanks_to.mcmod.statement=For providing the Simplified Chinese translations and wiki for various mods.
about.thanks_to.red_lnn.statement=For providing the default background image.
@@ -58,36 +58,36 @@ account.create.microsoft=Add a Microsoft Account
account.create.offline=Add an Offline Account
account.create.authlibInjector=Add an authlib-injector Account
account.email=Email
account.failed=Account refresh failed.
account.failed=Failed to refresh account.
account.failed.character_deleted=The player has already been deleted.
account.failed.connect_authentication_server=Unable to connect to the authentication server, your network connection may be down.
account.failed.connect_injector_server=Unable to connect to the authentication server. Please check your network and make sure you entered the correct URL.
account.failed.injector_download_failure=Unable to download the authlib-injector. Please check your network, or try switching to a different download source.
account.failed.invalid_credentials=Incorrect password or rate limited, please try again later.
account.failed.connect_authentication_server=Failed to connect to the authentication server, your network connection may be down.
account.failed.connect_injector_server=Failed to connect to the authentication server. Please check your network and make sure you entered the correct URL.
account.failed.injector_download_failure=Failed to download the authlib-injector. Please check your network, or try switching to a different download source.
account.failed.invalid_credentials=Incorrect password or rate limited. Please try again later.
account.failed.invalid_password=Invalid password.
account.failed.invalid_token=Please try logging in again.
account.failed.migration=Your account needs to be migrated to a Microsoft account. If you already did, you should re-login to your migrated Microsoft account instead.
account.failed.migration=Your account needs to be migrated to a Microsoft account. If you already did, you should log in to your migrated Microsoft account again.
account.failed.no_character=There are no characters linked to this account.
account.failed.server_disconnected=Unable to connect to the authentication server. You can log in offline mode or try logging in again.\n\
If you try several times and still fail, please try adding the account again.
account.failed.server_response_malformed=Invalid server response, the authentication server may not be working.
account.failed.server_disconnected=Failed to connect to the authentication server. You can log in using offline mode or try logging in again.\n\
If you try several times and still fail, please try logging in to the account again.
account.failed.server_response_malformed=Invalid server response. The authentication server may not be working.
account.failed.ssl=An SSL error occurred while connecting to the server. Please try updating your Java.
account.failed.wrong_account=You have logged in to the wrong account.
account.hmcl.hint=You need to click "Login" and complete the process in the opened browser window.
account.injector.add=New Auth Server
account.injector.empty=None (You can click "+" to add one)
account.injector.http=Warning: This server uses the unsafe HTTP protocol, anyone between your connection will be able to see your credentials in cleartext.
account.injector.http=Warning: This server uses the unsafe HTTP protocol. Anyone between your connections will be able to see your credentials in cleartext.
account.injector.link.homepage=Homepage
account.injector.link.register=Register
account.injector.server=Authentication Server
account.injector.server_url=Server URL
account.injector.server_name=Server Name
account.login=Login
account.login=Log in
account.login.hint=We never store your password.
account.login.skip=Login offline
account.login.skip=Log in offline
account.login.retry=Retry
account.login.refresh=Re-login
account.login.refresh.microsoft.hint=You need to re-add your Microsoft account due to the account authorization is invalid.
account.login.refresh=Log in again
account.login.refresh.microsoft.hint=You need to log in to your Microsoft account again because the account authorization is invalid.
account.logout=Logout
account.register=Register
account.manage=Account List
@@ -95,25 +95,25 @@ account.copy_uuid=Copy UUID of the Account
account.methods=Login Type
account.methods.authlib_injector=authlib-injector
account.methods.microsoft=Microsoft
account.methods.microsoft.birth=How to Update Your Account Birthday
account.methods.microsoft.birth=How to Change Your Account Birthday
account.methods.microsoft.close_page=Microsoft account authorization is now completed.\n\
\n\
There are some extra works for us, but you can safely close this tab for now.
account.methods.microsoft.deauthorize=Deauthorize
account.methods.microsoft.error.add_family=An adult must add you to a family in order for you to play Minecraft due to you are not yet 18 years old.
account.methods.microsoft.error.add_family_probably=Please check if the age indicated in your account settings is at least 18 years old. If not and you believe this is an error, you can click "How to Update Your Account Birthday" to learn how to change it.
account.methods.microsoft.error.add_family=An adult must add you to a family in order for you to play Minecraft because you are not yet 18 years old.
account.methods.microsoft.error.add_family_probably=Please check if the age indicated in your account settings is at least 18 years old. If not and you believe this is an error, you can click "How to Change Your Account Birthday" to learn how to change it.
account.methods.microsoft.error.country_unavailable=Xbox Live is not available in your current country/region.
account.methods.microsoft.error.missing_xbox_account=Your Microsoft account does not have a linked Xbox account yet. Please click "Create Profile / Edit Profile Name" to create one before continuing.
account.methods.microsoft.error.no_character=Your account does not own the Minecraft Java Edition.\nThe game profile may not have been created\nplease click "Create Profile / Edit Profile Name" to create it.
account.methods.microsoft.error.unknown=Failed to log in, error code: %d.
account.methods.microsoft.error.wrong_verify_method=Please log in using your password on the Microsoft account login page, and do not use a verification code to log in.
account.methods.microsoft.logging_in=Logging in...
account.methods.microsoft.hint=Please click "Login" and copy the code displayed here to complete the login process in the browser window that opens.\n\
account.methods.microsoft.hint=Please click "Log in" and copy the code displayed here to complete the login process in the browser window that opens.\n\
\n\
If the token used to log in to the Microsoft account is leaked, you can click "Deauthorize" to deauthorize it.
account.methods.microsoft.manual=Your device code is <b>%1$s</b>, please click here to copy.\n\
account.methods.microsoft.manual=Your device code is <b>%1$s</b>. Please click here to copy.\n\
\n\
After clicking "Login", you should complete the login process in the opened browser window. If it did not show, you can navigate to %2$s manually.\n\
After clicking "Log in", you should complete the login process in the opened browser window. If it did not show, you can navigate to %2$s manually.\n\
\n\
If the token used to log in to the Microsoft account is leaked, you can click "Deauthorize" to deauthorize it.
account.methods.microsoft.makegameidsettings=Create Profile / Edit Profile Name
@@ -122,8 +122,8 @@ account.methods.microsoft.purchase=Buy Minecraft
account.methods.microsoft.snapshot=You are using an unofficial build of HMCL. Please download the official build for login.
account.methods.microsoft.snapshot.website=Official Website
account.methods.offline=Offline
account.methods.offline.name.special_characters=Recommended to use English letters, numbers and underscores
account.methods.offline.name.invalid=Generally, game usernames only allow English letters, numbers, and underscores, and cannot exceed 16 characters in length.\n\
account.methods.offline.name.special_characters=Recommended to use English letters, numbers, and underscores
account.methods.offline.name.invalid=Generally, game usernames only allow English letters, numbers, and underscores and cannot exceed 16 characters in length.\n\
\n\
\ · Some legitimate usernames: HuangYu, huang_Yu, Huang_Yu_123;\n\
\ · Some illegal usernames: Huang Yu, Huang-Yu_%%%, Huang_Yu_hello_world_hello_world.\n\
@@ -137,7 +137,7 @@ account.methods.offline.uuid.malformed=Invalid format.
account.methods.forgot_password=Forgot Password
account.missing=No Accounts
account.missing.add=Click here to add one.
account.move_to_global=Convert to Global Account\nThe account information will be saved in a config file of the user directory.
account.move_to_global=Convert to Global Account\nThe account information will be saved in a config file of the current user directory of the system.
account.move_to_portable=Convert to Portable Account\nThe account information will be saved in a config file in the same directory as HMCL.
account.not_logged_in=Not Logged in
account.password=Password
@@ -154,7 +154,7 @@ account.skin.type.little_skin=LittleSkin
account.skin.type.little_skin.hint=You need to create a player with the same player name as your offline account on your skin provider site. Your skin will now be set to the skin assigned to your player on the skin provider site.
account.skin.type.local_file=Local Skin File
account.skin.upload=Upload/Edit Skin
account.skin.upload.failed=Unable to upload skin.
account.skin.upload.failed=Failed to upload skin.
account.skin.invalid_skin=Invalid skin file.
account.username=Username
@@ -191,6 +191,7 @@ chat=Join Group Chat
color.recent=Recommended
color.custom=Custom Color
crash.NoClassDefFound=Please verify the integrity of this software, or try updating your Java.
crash.user_fault=The launcher crashed due to a corrupted Java or system environment. Please make sure your Java or OS is installed properly.
@@ -252,7 +253,7 @@ curse.category.430=Thaumcraft
curse.category.422=Adventure and RPG
curse.category.413=Processing
curse.category.417=Energy
curse.category.415=Energy, Fluid and Item Transport
curse.category.415=Energy, Fluid, and Item Transport
curse.category.433=Forestry
curse.category.425=Miscellaneous
curse.category.4545=Applied Energistics 2
@@ -319,16 +320,16 @@ curse.sort.popularity=Popularity
curse.sort.total_downloads=Total Downloads
download=Download
download.hint=Install games and modpacks or download mods, resource packs and worlds.
download.hint=Install games and modpacks or download mods, resource packs, and worlds.
download.code.404=File not found on the remote server: %s
download.content=Addons
download.curseforge.unavailable=HMCL Nightly channel build does not support access to CurseForge, please use Release or Beta channel builds to download.
download.existing=The file cannot be saved due to it already exists. You can click "Save As" to save the file elsewhere.
download.curseforge.unavailable=HMCL Nightly channel build does not support access to CurseForge. Please use Release or Beta channel builds to download.
download.existing=The file cannot be saved because it already exists. You can click "Save As" to save the file elsewhere.
download.external_link=Visit Download Website
download.failed=Failed to download "%1$s", response code: %2$d.
download.failed.empty=No versions are available, please click here to go back.
download.failed.empty=No versions are available. Please click here to go back.
download.failed.no_code=Failed to download "%s".
download.failed.refresh=Unable to fetch version list. Please click here to retry.
download.failed.refresh=Failed to fetch version list. Please click here to retry.
download.game=New Game
download.provider.bmclapi=BMCLAPI (bangbang93, https://bmclapi2.bangbang93.com/)
download.provider.mojang=Official (OptiFine is provided by BMCLAPI)
@@ -336,43 +337,46 @@ download.provider.official=From Official Sources
download.provider.balanced=From Fastest Available
download.provider.mirror=From Mirror
download.java=Downloading Java
download.java.override=This Java version already exists, do you want to uninstall and reinstall it?
download.java.override=This Java version already exists. Do you want to uninstall and reinstall it?
download.javafx=Downloading dependencies for the launcher...
download.javafx.notes=We are currently downloading dependencies for HMCL from the Internet.\n\
\n\
You can click "Change Download Source" to choose download source or\nclick "Cancel" to stop and exit.\n\
You can click "Change Download Source" to choose the download source, or\nclick "Cancel" to stop and exit.\n\
Note: If your download speed is too slow, you can try switching to another mirror.
download.javafx.component=Downloading module "%s"
download.javafx.prepare=Preparing to download
exception.access_denied=HMCL is unable to access the file "%s", it may be locked by another process.\n\
exception.access_denied=HMCL is unable to access the file "%s". It may be locked by another process.\n\
\n\
For Windows users, you can open "Resource Monitor" to check if another process is currently using it. If so, you can try again after closing that process.\n\
If not, please check if your account has enough permissions to access it.
exception.artifact_malformed=Cannot verify the integrity of the downloaded files.
exception.ssl_handshake=Unable to establish SSL connection due to missing SSL certificates in current Java installation. You can try opening HMCL in another Java, then try again.
exception.ssl_handshake=Failed to establish an SSL connection due to the lack of an SSL certificate in the current Java installation. You can try opening HMCL in another Java and try again.
extension.bat=Windows Batch File (.bat)
extension.mod=Mod File
extension.png=Image File
extension.ps1=Windows PowerShell Script (.ps1)
extension.sh=Shell Script (.sh)
fatal.javafx.incompatible=Missing JavaFX environment.\n\
Hello Minecraft! Launcher cannot automatically install JavaFX on Java <11.\n\
Please update your Java to version 11 or later.
fatal.javafx.incomplete=The JavaFX environment is incomplete.\n\
Please try replacing your Java or reinstalling OpenJFX.
fatal.javafx.missing=Missing JavaFX environment. Please open Hello Minecraft! Launcher with a Java which includes OpenJFX.
fatal.config_change_owner_root=You are using the root account to open Hello Minecraft! Launcher, this may cause you to fail to open HMCL with other account in the future.\n\
fatal.javafx.missing=Missing JavaFX environment. Please open Hello Minecraft! Launcher with Java, which includes OpenJFX.
fatal.config_change_owner_root=You are using the root account to open Hello Minecraft! Launcher. This may cause you to fail to open HMCL with another account in the future.\n\
Do you still want to continue?
fatal.config_in_temp_dir=You are opening Hello Minecraft! Launcher in a temporary directory, your settings and game data may be lost.\n\
fatal.config_in_temp_dir=You are opening Hello Minecraft! Launcher in a temporary directory. Your settings and game data may be lost.\n\
It is recommended to move HMCL to another location and reopen it.\n\
Do you still want to continue?
fatal.config_loading_failure=Cannot load configuration files.\n\
Please make sure that Hello Minecraft! Launcher has read and write access to "%s" and the files in it.\n\
For macOS, try putting HMCL somewhere with permissions other than "Desktop", "Downloads" and "Documents" and try again.
fatal.config_loading_failure.unix=Hello Minecraft! Launcher could not load the profile due to it was created by user %1$s.\n\
For macOS, try putting HMCL somewhere with permissions other than "Desktop", "Downloads", and "Documents" and try again.
fatal.config_loading_failure.unix=Hello Minecraft! Launcher could not load the configuration file because it was created by user "%1$s".\n\
Please open HMCL as root user (not recommended), or execute the following command in the terminal to change the ownership of the configuration file to the current user:\n%2$s
fatal.mac_app_translocation=Due to macOS security mechanisms, Hello Minecraft! Launcher is isolated to a temporary directory by the OS.\n\
Please move HMCL to a different directory before attempting to open, otherwise your settings and game data may be lost after restarting.\n\
Please move HMCL to a different directory before attempting to open. Otherwise, your settings and game data may be lost after restarting.\n\
Do you still want to continue?
fatal.migration_requires_manual_reboot=Hello Minecraft! Launcher has been upgraded. Please restart the launcher.
fatal.apply_update_failure=We are sorry, but Hello Minecraft! Launcher is unable to update automatically.\n\
@@ -382,28 +386,28 @@ fatal.apply_update_failure=We are sorry, but Hello Minecraft! Launcher is unable
fatal.apply_update_need_win7=Hello Minecraft! Launcher cannot automatically update on Windows XP/Vista.\n\
\n\
You can update manually by downloading a newer launcher version from %s.
fatal.samba=If you opened Hello Minecraft! Launcher from a Samba network drive, some features might not be working. Please try updating your Java or copy and open the launcher in a local directory.
fatal.illegal_char=Your user path contains an illegal character "=", you will not be able to use authlib-injector or change the skin of your offline account.
fatal.unsupported_platform=Minecraft is not yet fully supported for your platform, so you may experience missing functionality, or even be unable to launch the game.\n\
fatal.samba=If you opened Hello Minecraft! Launcher from a Samba network drive, some features might not be working. Please try updating your Java or moving the launcher to another directory.
fatal.illegal_char=Your user path contains an illegal character "=". You will not be able to use authlib-injector or change the skin of your offline account.
fatal.unsupported_platform=Minecraft is not yet fully supported for your platform, so you may experience missing functionality or even be unable to launch the game.\n\
\n\
If you cannot launch Minecraft 1.17 and later, you can try switching the "Renderer" to "Software" in "Global/Instance-specific Settings → Advanced Settings" to use CPU rendering for better compatibility.
fatal.unsupported_platform.loongarch=Hello Minecraft! Launcher has provided support for Loongson platform.\n\
If you encounter problems when playing game, you can visit https://docs.hmcl.net/groups.html for help.
fatal.unsupported_platform.osx_arm64=Hello Minecraft! Launcher has provided support for Apple silicon platform, using native ARM java to launch games to get a smoother game experience.\n\
If you encounter problems when playing game, launching the game with Java based on x86-64 architecture may have better compatibility.
fatal.unsupported_platform.windows_arm64=Hello Minecraft! Launcher has provided native support for the Windows on Arm platform. If you encounter problems when playing game, please try launching the game with Java based on x86 architecture.\n\
fatal.unsupported_platform.loongarch=Hello Minecraft! Launcher has provided support for the Loongson platform.\n\
If you encounter problems when playing a game, you can visit https://docs.hmcl.net/groups.html for help.
fatal.unsupported_platform.osx_arm64=Hello Minecraft! Launcher has provided support for the Apple silicon platform, using native ARM Java to launch games to get a smoother game experience.\n\
If you encounter problems when playing a game, launching the game with Java based on x86-64 architecture may have better compatibility.
fatal.unsupported_platform.windows_arm64=Hello Minecraft! Launcher has provided native support for the Windows on Arm platform. If you encounter problems when playing a game, please try launching the game with Java based on x86 architecture.\n\
\n\
If you are using the <b>Qualcomm</b> platform, you may need to install the <a href="ms-windows-store://pdp/?productid=9NQPSL29BFFF">OpenGL Compatibility Pack</a> before playing games.\n\
Click the link to navigate to Microsoft Store and install the compatibility pack.
Click the link to navigate to the Microsoft Store and install the compatibility pack.
feedback=Feedback
feedback.channel=Feedback Channel
feedback.discord=Discord
feedback.discord.statement=Join our Discord community.
feedback.discord.statement=Welcome to join our Discord server.
feedback.github=GitHub Issues
feedback.github.statement=Submit an issue on GitHub.
feedback.qq_group=HMCL User Group
feedback.qq_group.statement=Welcome to join our user group.
feedback.qq_group=HMCL User QQ Group
feedback.qq_group.statement=Welcome to join our user QQ group.
file=File
@@ -417,14 +421,14 @@ folder.saves=Saves
folder.screenshots=Screenshots
game=Games
game.crash.feedback=<b>Please do not share screenshots of this interface with others!</b> If you ask for help from others, please click to export the game crash information in the lower left corner and send the exported file to others for analysis.
game.crash.feedback=<b>Please do not share screenshots of this interface with others!</b> If you ask for help from others, please click <b>"Export Crash Logs"</b> and send the exported file to others for analysis.
game.crash.info=Crash Info
game.crash.reason=Crash Cause
game.crash.reason.analyzing=Analyzing...
game.crash.reason.multiple=Several reasons detected:\n\n
game.crash.reason.block=The game crashed due to a block in world.\n\
game.crash.reason.block=The game crashed due to a block in the world.\n\
\n\
You can try removing this block using MCEdit or delete that mod that added it.\n\
You can try removing this block using MCEdit or deleting the mod that added it.\n\
\n\
Block Type: %1$s\n\
Location: %2$s
@@ -432,26 +436,26 @@ game.crash.reason.bootstrap_failed=The game crashed due to mod "%1$s".\n\
\n\
You can try deleting or updating it.
game.crash.reason.config=The game crashed due to a mod "%1$s" cannot parse its config file "%2$s".
game.crash.reason.debug_crash=The game crashed due to you manually triggered it. So, you probably know why.
game.crash.reason.debug_crash=The game crashed due to you triggering it manually. So you probably know why.
game.crash.reason.duplicated_mod=The game cannot continue to run due to duplicate mods "%1$s".\n\
\n\
%2$s\n\
\n\
Each mod can only be installed once, please delete the duplicate mod and try again.
game.crash.reason.entity=The game crashed due to an entity in world.
Each mod can only be installed once. Please delete the duplicate mod and try again.
game.crash.reason.entity=The game crashed due to an entity in the world.\n\
\n\
You can try removing this entity using MCEdit or delete that mod that added it.\n\
You can try removing the entity using MCEdit or deleting the mod that added it.\n\
\n\
Entity Type: %1$s\n\
Location: %2$s
game.crash.reason.modmixin_failure=The game crashed due to some mod injection failed.\n\
game.crash.reason.modmixin_failure=The game crashed due to some mod injection failure.\n\
\n\
This generally means that the mod has a bug or is incompatible with the current environment.\n\
\n\
You can check the log to find the error mod.
game.crash.reason.mod_repeat_installation=The game crashed due to duplicate mods.\n\
\n\
Each mod can only be installed once, please delete the duplicate mod and then relaunch the game.
Each mod can only be installed once. Please delete the duplicate mod and then relaunch the game.
game.crash.reason.forge_error=Forge/NeoForge may have provided error information.\n\
\n\
You can view the log and make corresponding processing according to the log information in the error report.\n\
@@ -459,12 +463,12 @@ game.crash.reason.forge_error=Forge/NeoForge may have provided error information
If you do not see the error message, you can view the error report to understand how the error occurred.\n\
%1$s
game.crash.reason.mod_resolution0=The game crashed due to some mod problems. You can check the log to find the error mod(s).
game.crash.reason.mixin_apply_mod_failed=The game crashed due to mixin failed to apply the "%1$s" mod.\n\
game.crash.reason.mixin_apply_mod_failed=The game crashed due to the mixin could not be applied to the "%1$s" mod.\n\
\n\
You can try deleting or updating the mod to resolve the problem.
game.crash.reason.java_version_is_too_high=The game crashed due to the Java version is too high to continue running.\n\
game.crash.reason.java_version_is_too_high=The game crashed due to the Java version being too high to continue running.\n\
\n\
Please use an older Java version in "Global/Instance-specific Settings → Java", and then launch the game.\n\
Please use an earlier Java version in "Global/Instance-specific Settings → Java" and then launch the game.\n\
\n\
If not, you can download it from <a href="https://www.java.com/download/">java.com (Java 8)</a> or <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java 17)</a> and other distributions to download and install one (restart the launcher after installation).
game.crash.reason.need_jdk11=The game crashed due to an inappropriate Java VM version.\n\
@@ -478,27 +482,27 @@ game.crash.reason.mod_name=The game crashed due to mod file name problems.\n\
game.crash.reason.incomplete_forge_installation=The game cannot continue to run due to an incomplete installation of Forge/NeoForge.\n\
\n\
Please reinstall Forge/NeoForge in "Edit Instance → Loaders".
game.crash.reason.fabric_version_0_12=Fabric Loader 0.12 or later are incompatible with currently installed mods. You need to downgrade it to 0.11.7.
game.crash.reason.fabric_version_0_12=Fabric Loader 0.12 or later is incompatible with currently installed mods. You need to downgrade it to 0.11.7.
game.crash.reason.fabric_warnings=The Fabric warned:\n\
\n\
%1$s
game.crash.reason.file_already_exists=The game crashed due to file "%1$s" already exists.\n\
\n\
You can try backing up and delete that file, then relaunch the game.
You can try backing up and deleting that file, then relaunching the game.
game.crash.reason.file_changed=The game crashed due to file "%1$s" already exists.\n\
\n\
You can try backing up and delete that file, then relaunch the game.
You can try backing up and deleting that file, then relaunching the game.
game.crash.reason.gl_operation_failure=The game crashed due to some mods, shaders, or resource packs.\n\
\n\
Please disable the mods, shaders or resource packs you are using and then try again.
game.crash.reason.graphics_driver=The game crashed due to an problem with your graphics driver.\n\
Please disable the mods, shaders, or resource packs you are using and then try again.
game.crash.reason.graphics_driver=The game crashed due to a problem with your graphics driver.\n\
\n\
Please try again after updating your graphics driver to the latest version.\n\
\n\
If your PC has a discrete graphics card, you need to check whether the game uses integrated/core graphics. If so, please open the launcher using your discrete graphics card. If the problem persists, you probably should consider using a new graphics card or a new PC.\n\
\n\
If you are using your integrated graphics card, please notice that Minecraft 1.16.5 or older requires <a href="https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html">Java 1.8.0_51 or older</a> for Intel(R) Core(TM) 3000 processor series or earlier.
game.crash.reason.macos_failed_to_find_service_port_for_display=The current game cannot continue due to a failure to initialize the OpenGL window on the Apple silicon platform.\n\
If you are using your integrated graphics card, please notice that Minecraft 1.16.5 or earlier requires <a href="https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html">Java 1.8.0_51 or earlier</a> for Intel(R) Core(TM) 3000 processor series or earlier.
game.crash.reason.macos_failed_to_find_service_port_for_display=The game cannot continue due to a failure to initialize the OpenGL window on the Apple silicon platform.\n\
\n\
For this problem, HMCL does not have direct solutions at the moment. Please try opening any browser and going fullscreen, then return to HMCL, launch the game, and <b>quickly return to the browser page</b> before the game window pops up, wait for the game window to appear, and then switch back to the game window.
game.crash.reason.illegal_access_error=The game crashed due to some mod(s).\n\
@@ -506,49 +510,49 @@ game.crash.reason.illegal_access_error=The game crashed due to some mod(s).\n\
If you know this: "%1$s", you can update or delete the mod(s) and then try again.
game.crash.reason.install_mixinbootstrap=The game crashed due to missing MixinBootstrap.\n\
\n\
You can try installing <a href="https://www.curseforge.com/minecraft/mc-mods/mixinbootstrap">MixinBootstrap</a> to resolve the problem. If it crashes after installation, try adding an exclamation mark (!) in front of the file name of this mod. in front of the file name of the mod to try to resolve the problem.
You can try installing <a href="https://www.curseforge.com/minecraft/mc-mods/mixinbootstrap">MixinBootstrap</a> to resolve the problem. If it crashes after installation, try adding an exclamation mark (!) in front of the file name of this mod to try to resolve the problem.
game.crash.reason.optifine_is_not_compatible_with_forge=The game crashes due to OptiFine being incompatible with the currently installed Forge.\n\
\n\
Please navigate to<a href="https://optifine.net/downloads">the official website of OptiFine</a>, check whether the Forge version is compatible with OptiFine, and reinstall the instance in strict accordance with the corresponding version, or change the OptiFine version in "Edit Instance → Loaders".\n\
\n\
After testing, we believe that too high or too low OptiFine versions may cause crashes.
game.crash.reason.mod_files_are_decompressed=The game crashed due to the mod file has been extracted.\n\
game.crash.reason.mod_files_are_decompressed=The game crashed due to the mod file having been extracted.\n\
\n\
Please put the entire mod file directly into the mod directory!\n\
\n\
If extract will cause errors in the game, please delete the extracted mod in the mod directory, and then launch the game.
game.crash.reason.shaders_mod=The game crashed due to both OptiFine and Shaders mod are installed.\n\
If extract will cause errors in the game, please delete the extracted mod in the mod directory and then launch the game.
game.crash.reason.shaders_mod=The game crashed due to both OptiFine and Shaders mods being installed.\n\
\n\
Just remove Shaders mod due to OptiFine has built-in support for shaders.
game.crash.reason.rtss_forest_sodium=The game crashed due to RivaTuner Statistics Server (RTSS) is incompatible with Sodium.\n\
Just remove Shaders mod due to OptiFine having built-in support for shaders.
game.crash.reason.rtss_forest_sodium=The game crashed due to RivaTuner Statistics Server (RTSS) being incompatible with Sodium.\n\
\n\
Click <a href="https://github.com/CaffeineMC/sodium-fabric/wiki/Known-Issues#rtss-incompatible">here</a> for more details.
game.crash.reason.too_many_mods_lead_to_exceeding_the_id_limit=The game crashed due to you have installed too many mods, which exceeds the ID limit of the game.\n\
game.crash.reason.too_many_mods_lead_to_exceeding_the_id_limit=The game crashed due to you having installed too many mods, which exceeds the ID limit of the game.\n\
\n\
Please try installing<a href="https://www.curseforge.com/minecraft/mc-mods/jeid">JEID</a>, or delete some large mods.
Please try installing<a href="https://www.curseforge.com/minecraft/mc-mods/jeid">JEID</a> or deleting some large mods.
game.crash.reason.night_config_fixes=The game crashed due to some problems with Night Config.\n\
\n\
You can try to install the <a href="https://www.curseforge.com/minecraft/mc-mods/night-config-fixes">Night Config Fixes</a> mod, which may help you this problem.\n\
You can try installing the <a href="https://www.curseforge.com/minecraft/mc-mods/night-config-fixes">Night Config Fixes</a> mod, which may help you with this problem.\n\
\n\
For more information, visit the <a href="https://github.com/Fuzss/nightconfigfixes">GitHub repository</a> of this mod.
game.crash.reason.optifine_causes_the_world_to_fail_to_load=The game may not continue to run due to OptiFine.\n\
\n\
This problem only occurs in a specific OptiFine version. You can try changing OptiFine version in "Edit Instance → Loaders".
game.crash.reason.jdk_9=The game crashed due to the Java version is too new for this instance.\n\
This problem only occurs in a specific OptiFine version. You can try changing the OptiFine version in "Edit Instance → Loaders".
game.crash.reason.jdk_9=The game crashed due to the Java version being too new for this instance.\n\
\n\
You need to download and install Java 8 and choose it in "Global/Instance-specific Settings → Java".
game.crash.reason.jvm_32bit=The game crashed due to the current memory allocation exceeds the limit of the 32-bit Java VM.\n\
game.crash.reason.jvm_32bit=The game crashed due to the current memory allocation exceeding the limit of the 32-bit Java VM.\n\
\n\
If your OS is 64-bit, please install and use a 64-bit Java version. Otherwise, you may need to reinstall a 64-bit OS or get a moderner PC.\n\
\n\
Or, you can disable the "Automatically Allocate" option in "Global/Instance-specific Settings → Memory", and set the maximum memory allocation size to 1024 MB or below.
Or, you can disable the "Automatically Allocate" option in "Global/Instance-specific Settings → Memory" and set the maximum memory allocation size to 1024 MB or below.
game.crash.reason.loading_crashed_forge=The game crashed due to mod "%1$s" (%2$s).\n\
\n\
You can try deleting or updating it.
game.crash.reason.loading_crashed_fabric=The game crashed due to mod "%1$s".\n\
\n\
You can try deleting or updating it.
game.crash.reason.mac_jdk_8u261=The game crashed due to your current Forge or OptiFine version is not compatible with your Java installation.\n\
game.crash.reason.mac_jdk_8u261=The game crashed due to your current Forge or OptiFine version not being compatible with your Java installation.\n\
\n\
Please try updating Forge and OptiFine, or try using Java 8u251 or earlier versions.
game.crash.reason.forge_repeat_installation=The game crashed due to a duplicate installation of Forge. <a href="https://github.com/HMCL-dev/HMCL/issues/1880">This is a known problem</a>\n\
@@ -561,24 +565,24 @@ game.crash.reason.optifine_repeat_installation=The game crashed due to repeated
Please delete OptiFine in the mod directory or uninstall it in "Edit Instance → Loaders".
game.crash.reason.memory_exceeded=The game crashed due to too much memory allocated for a small page file.\n\
\n\
You can try disable the "Automatically Allocate" option in "Global/Instance-specific Settings → Memory", and adjust the value till the game launches.\n\
You can try disabling the "Automatically Allocate" option in "Global/Instance-specific Settings → Memory" and adjust the value till the game launches.\n\
\n\
You can also try increasing the page file size in system settings.
game.crash.reason.mod=The game crashed due to the mod "%1$s".\n\
\n\
You may update or delete the mod and then try again.
game.crash.reason.mod_resolution=The game crashed due to mod resolution failure.\n\
game.crash.reason.mod_resolution=The game cannot continue to run due to mod dependency problems.\n\
\n\
Fabric provided the following details:\n\
\n\
%1$s
game.crash.reason.forgemod_resolution=The game crashed due to mod resolution failure.\n\
game.crash.reason.forgemod_resolution=The game cannot continue to run due to mod dependency problems.\n\
\n\
Forge/NeoForge provided the following details:\n\
%1$s
game.crash.reason.forge_found_duplicate_mods=The game crashed due to a duplicate mods problem. Forge/NeoForge provides the following information:\n\
%1$s
game.crash.reason.mod_resolution_collection=The game crashed due to the mod version is not compatible.\n\
game.crash.reason.mod_resolution_collection=The game crashed because the mod version is not compatible.\n\
\n\
"%1$s" requires "%2$s".\n\
\n\
@@ -586,12 +590,12 @@ game.crash.reason.mod_resolution_collection=The game crashed due to the mod vers
game.crash.reason.mod_resolution_conflict=The game crashed due to conflicting mods.\n\
\n\
"%1$s" is incompatible with "%2$s".
game.crash.reason.mod_resolution_missing=The game crashed due to some dependency mods are not installed.\n\
game.crash.reason.mod_resolution_missing=The game crashed due to some dependency mods not being installed.\n\
\n\
"%1$s" requires mod "%2$s".\n\
\n\
This means that you have to download and install "%2$s" first to continue playing.
game.crash.reason.mod_resolution_missing_minecraft=The game crashed due to a mod is incompatible with the current Minecraft version.\n\
game.crash.reason.mod_resolution_missing_minecraft=The game crashed due to a mod being incompatible with the current Minecraft version.\n\
\n\
"%1$s" requires Minecraft version %2$s.\n\
\n\
@@ -600,10 +604,10 @@ game.crash.reason.mod_resolution_missing_minecraft=The game crashed due to a mod
Otherwise, you should install a version that is compatible with this Minecraft version.
game.crash.reason.mod_resolution_mod_version=%1$s (Version: %2$s)
game.crash.reason.mod_resolution_mod_version.any=%1$s (Any Version)
game.crash.reason.modlauncher_8=The game crashed due to your current Forge version is not compatible with your Java installation, please try updating Forge.
game.crash.reason.modlauncher_8=The game crashed due to your current Forge version not being compatible with your Java installation. Please try updating Forge.
game.crash.reason.no_class_def_found_error=The game cannot continue to run due to incomplete code.\n\
\n\
Your game instance is missing %1$s, this might be due to a mod missing, an incompatible mod installed, or some files might be corrupted.\n\
Your game instance is missing %1$s. This might be due to a mod missing, an incompatible mod installed, or some files being corrupted.\n\
\n\
You may need to reinstall the game and all mods or ask someone for help.
game.crash.reason.no_such_method_error=The game cannot continue to run due to incomplete code.\n\
@@ -611,38 +615,38 @@ game.crash.reason.no_such_method_error=The game cannot continue to run due to in
Your game instance might be missing a mod, installed an incompatible mod, or some files might be corrupted.\n\
\n\
You may need to reinstall the game and all mods or ask someone for help.
game.crash.reason.opengl_not_supported=The game crashed due to OpenGL is not supported by your graphics driver.\n\
game.crash.reason.opengl_not_supported=The game crashed due to OpenGL not being supported by your graphics driver.\n\
\n\
If you are streaming the game over the Internet or using a remote desktop environment, please play the game on your local one.\n\
\n\
Or, you can try updating your driver to the latest version and then try again.\n\
\n\
If your PC has a discrete graphics card, please make sure the game is actually using it for rendering. If the problem persists, please consider getting a new graphics card or a new PC.
game.crash.reason.openj9=The game is unable to run on an OpenJ9 VM. Please switch to a Java that uses the Hotspot VM in "Global/Instance-specific Settings → Java" and relaunch the game. If do not have one, you can download one online.
game.crash.reason.out_of_memory=The game crashed due to it ran out of memory.\n\
game.crash.reason.openj9=The game is unable to run on an OpenJ9 VM. Please switch to a Java that uses the Hotspot VM in "Global/Instance-specific Settings → Java" and relaunch the game. If you do not have one, you can download one online.
game.crash.reason.out_of_memory=The game crashed due to it running out of memory.\n\
\n\
Maybe because there is not enough memory available, or too many mods installed. You can try resolving it by increasing the allocated memory in "Global/Instance-specific Settings → Memory".\n\
Maybe because there is not enough memory available or too many mods installed. You can try resolving it by increasing the allocated memory in "Global/Instance-specific Settings → Memory".\n\
\n\
If you still encounter these problems, you may need a better PC.
game.crash.reason.resolution_too_high=The game crashed due to the resource pack resolution being too high.\n\
\n\
You should switch to a resource pack with lower resolution, or consider buying a better graphics card with more VRAM.
You should switch to a resource pack with lower resolution or consider buying a better graphics card with more VRAM.
game.crash.reason.stacktrace=The crash reason is unknown. You can view its details by clicking "Logs".\n\
\n\
There are some keywords that might contain some mod names. You can search them online to figure out the problem yourself.\n\
\n\
%s
game.crash.reason.too_old_java=The game crashed due to you are using an outdated Java VM version.\n\
game.crash.reason.too_old_java=The game crashed due to you using an outdated Java VM version.\n\
\n\
You need to switch to a newer version (%1$s) of Java in "Global/Instance-specific Settings → Java" and then relaunch the game. You can download Java from <a href="https://learn.microsoft.com/java/openjdk/download">here</a>.
game.crash.reason.unknown=We are not able to figure out why the game crashed, please refer to the game logs.
game.crash.reason.unsatisfied_link_error=Unable to launch Minecraft due to missing libraries: %1$s.\n\
game.crash.reason.unknown=We are not able to figure out why the game crashed. Please refer to the game logs.
game.crash.reason.unsatisfied_link_error=Failed to launch Minecraft due to missing libraries: %1$s.\n\
\n\
If you have edited native library path, please make sure these libraries do exist. Or, please try launching again after reverting it to default.\n\
If you have edited the native library path, please make sure these libraries do exist. Or, please try launching again after reverting it to default.\n\
\n\
If you did not, please check if you have missing dependency mods.\n\
\n\
Otherwise, if you believe this is caused by HMCL, please feedback to us.
Otherwise, if you believe this is caused by HMCL, please provide feedback to us.
game.crash.title=Game Crashed
game.directory=Game Path
game.version=Game Version
@@ -659,31 +663,31 @@ input.url=The input must be a valid URL.
install=New Instance
install.change_version=Change Version
install.change_version.confirm=Are you sure you want to switch %s from version %s to %s?
install.failed=Installation Failed
install.failed=Failed to install
install.failed.downloading=We are unable to download some required files.
install.failed.downloading.detail=Unable to download file: %s
install.failed.downloading.detail=Failed to download file: %s
install.failed.downloading.timeout=Download timeout when fetching: %s
install.failed.install_online=Unable to identify the provided file. If you are installing a mod, navigate to the "Mods" page.
install.failed.install_online=Failed to identify the provided file. If you are installing a mod, navigate to the "Mods" page.
install.failed.malformed=The downloaded files are corrupted. You can try resolving this problem by switching to another download source in "Settings → Download → Download Source".
install.failed.optifine_conflict=Cannot install both OptiFine and Fabric on Minecraft 1.13 or later.
install.failed.optifine_forge_1.17=For Minecraft 1.17.1, Forge only compatible with OptiFine H1 pre2 or later. You can install them by checking "Snapshots" when choosing an OptiFine version in HMCL.
install.failed.optifine_forge_1.17=For Minecraft 1.17.1, Forge is only compatible with OptiFine H1 pre2 or later. You can install them by checking "Snapshots" when choosing an OptiFine version in HMCL.
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.depend=Requires %s
install.installer.fabric=Fabric
install.installer.fabric-api=Fabric API
install.installer.fabric-api.warning=Warning: Fabric API 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 Fabric API will not work. If you do want to change these settings, you should reinstall it.
install.installer.fabric-api.warning=Warning: Fabric API 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 Fabric API will not work. If you do want to change these settings, you should reinstall it.
install.installer.forge=Forge
install.installer.neoforge=NeoForge
install.installer.game=Minecraft
install.installer.incompatible=Incompatible with %s
install.installer.install=Install %s
install.installer.install_offline=Install/Update From Local File
install.installer.install_offline=Install/Update from Local File
install.installer.install_offline.extension=(Neo)Forge/OptiFine installer
install.installer.install_offline.tooltip=We support using the local (Neo)Forge/OptiFine installer.
install.installer.install_online=Online Install
install.installer.install_online.tooltip=We currently support Forge, NeoForge, OptiFine, Fabric, Quilt and LiteLoader.
install.installer.install_online.tooltip=We currently support Forge, NeoForge, OptiFine, Fabric, Quilt, and LiteLoader.
install.installer.liteloader=LiteLoader
install.installer.not_installed=Do not install
install.installer.optifine=OptiFine
@@ -729,43 +733,43 @@ java.reveal=Reveal the Java directory
java.uninstall=Uninstall Java
java.uninstall.confirm=Are you sure you want to uninstall this Java? This action cannot be undone!
lang=English (United States)
lang=English
lang.default=Use System Locales
launch.advice=%s Do you still want to continue to launch?
launch.advice.multi=The following problems were detected:\n\n%s\n\nThese problems may cause unable to launch the game or affect the game experience.\nDo you still want to continue to launch?
launch.advice.java.auto=The current Java VM version does not compatible with the instance.\n\nClick "Yes" to automatically choose the most compatible Java VM version. Or, you can navigate to "Global/Instance-specific Settings → Java" to choose one yourself.
launch.advice.java.modded_java_7=Minecraft 1.7.2 and older versions require Java 7 or earlier.
launch.advice.multi=The following problems were detected:\n\n%s\n\nThese problems may cause you to be unable to launch the game or affect the game experience. \nDo you still want to continue to launch?
launch.advice.java.auto=The current Java VM version is not compatible with the instance.\n\nClick "Yes" to automatically choose the most compatible Java VM version. Or, you can navigate to "Global/Instance-specific Settings → Java" to choose one yourself.
launch.advice.java.modded_java_7=Minecraft 1.7.2 and earlier versions require Java 7 or earlier.
launch.advice.corrected=We have resolved the Java VM problem. If you still want to use your choice of Java version, you can disable the "Do not check Java VM compatibility" in "Global/Instance-specific Settings → Advanced Settings".
launch.advice.uncorrected=If you still want to use your choice of Java version, you can disable the "Do not check Java VM compatibility" in "Global/Instance-specific Settings → Advanced Settings".
launch.advice.different_platform=The 64-bit Java version is recommended for your device, but you have installed a 32-bit one.
launch.advice.forge2760_liteloader=Forge version 2760 is not compatible with LiteLoader, please consider upgrading Forge to version 2773 or later.
launch.advice.forge2760_liteloader=Forge version 2760 is not compatible with LiteLoader. Please consider upgrading Forge to version 2773 or later.
launch.advice.forge28_2_2_optifine=Forge version 28.2.2 or later is not compatible with OptiFine. Please consider downgrading Forge to version 28.2.1 or earlier.
launch.advice.forge37_0_60=Forge versions earlier than 37.0.60 are not compatible with Java 17. Please update Forge to 37.0.60 or later, or launch the game with Java 16.
launch.advice.java8_1_13=Minecraft 1.13 and later can only be run on Java 8 or later. Please use Java 8 or later versions.
launch.advice.java8_51_1_13=Minecraft 1.13 may crash on Java 8 versions earlier than 1.8.0_51. Please install the latest Java 8 version.
launch.advice.java9=You cannot launch Minecraft 1.12 or earlier with Java 9 or later, please use Java 8 instead.
launch.advice.java9=You cannot launch Minecraft 1.12 or earlier with Java 9 or later. Please use Java 8 instead.
launch.advice.modded_java=Some mods may not be compatible with newer versions of Java. It is recommended to use Java %s to launch Minecraft %s.
launch.advice.modlauncher8=The Forge version you are using is not compatible with the current Java version, please try updating Forge.
launch.advice.modlauncher8=The Forge version you are using is not compatible with the current Java version. Please try updating Forge.
launch.advice.newer_java=You are using the old Java to launch the game. It is recommended to update to Java 8, otherwise some mods may cause the game to crash.
launch.advice.not_enough_space=You have allocated a memory size larger than the actual %d MB of memory installed on your PC. You may experience degraded performance, or even be unable to launch the game.
launch.advice.require_newer_java_version=Current game version requires Java %s, but we could not find one. Do you want to download one now?
launch.advice.not_enough_space=You have allocated a memory size larger than the actual %d MB of memory installed on your PC. You may experience degraded performance or even be unable to launch the game.
launch.advice.require_newer_java_version=The current game version requires Java %s, but we could not find one. Do you want to download one now?
launch.advice.too_large_memory_for_32bit=You have allocated a memory size larger than the memory limitation of the 32-bit Java installation. You may be unable to launch the game.
launch.advice.vanilla_linux_java_8=Minecraft 1.12.2 or before only supports Java 8 for the Linux x86-64 platform, due to the later versions cannot load 32-bit native libraries like liblwjgl.so\n\nPlease download it from java.com, or install OpenJDK 8.
launch.advice.vanilla_x86.translation=Minecraft is not fully supported for your platform, so you may experience missing functionality, or even be unable to launch the game.\nYou can download Java for the <b>x86-64</b> architecture <a href="https://learn.microsoft.com/java/openjdk/download">here</a> for a full gaming experience.
launch.advice.vanilla_linux_java_8=Minecraft 1.12.2 or earlier only supports Java 8 for the Linux x86-64 platform because the later versions cannot load 32-bit native libraries like liblwjgl.so\n\nPlease download it from java.com or install OpenJDK 8.
launch.advice.vanilla_x86.translation=Minecraft is not fully supported for your platform, so you may experience missing functionality or even be unable to launch the game.\nYou can download Java for the <b>x86-64</b> architecture <a href="https://learn.microsoft.com/java/openjdk/download">here</a> for a full gaming experience.
launch.advice.unknown=The game cannot be launched due to the following reasons:
launch.failed=Failed to launch
launch.failed.cannot_create_jvm=We are unable to create a Java VM. It may be caused by incorrect Java VM arguments. You can try resolving it by removing all arguments you added in "Global/Instance-specific Settings → Advanced Settings → Java VM Options".
launch.failed.creating_process=We are unable to create a new process, please check your Java path.\n
launch.failed.creating_process=We are unable to create a new process. Please check your Java path.\n
launch.failed.command_too_long=The command length exceeds the maximum length of a bat script. Please try exporting it as a PowerShell script.
launch.failed.decompressing_natives=Unable to extract native libraries.\n
launch.failed.download_library=Unable to download libraries "%s".
launch.failed.executable_permission=Unable to make the launch script executable.
launch.failed.decompressing_natives=Failed to extract native libraries.\n
launch.failed.download_library=Failed to download libraries "%s".
launch.failed.executable_permission=Failed to make the launch script executable.
launch.failed.execution_policy=Set Execution Policy
launch.failed.execution_policy.failed_to_set=Unable to set execution policy
launch.failed.execution_policy.failed_to_set=Failed to set execution policy
launch.failed.execution_policy.hint=The current execution policy prevents the execution of PowerShell scripts.\n\nClick "OK" to allow the current user to execute PowerShell scripts, or click "Cancel" to keep it as it is.
launch.failed.exited_abnormally=Game crashed. Please refer to the crash log for more details.
launch.failed.java_version_too_low=The Java version you specified is too low, please reset the Java version.
launch.failed.no_accepted_java=Unable to find a compatible Java version, do you want to launch the game with the default Java?\nClick "Yes" to launch the game with the default Java.\nOr, you can navigate to "Global/Instance-specific Settings → Java" to choose one yourself.
launch.failed.java_version_too_low=The Java version you specified is too low. Please reset the Java version.
launch.failed.no_accepted_java=Failed to find a compatible Java version, do you want to launch the game with the default Java?\nClick "Yes" to launch the game with the default Java.\nOr, you can navigate to "Global/Instance-specific Settings → Java" to choose one yourself.
launch.failed.sigkill=Game was forcibly terminated by the user or system.
launch.state.dependencies=Resolving dependencies
launch.state.done=Launched
@@ -773,7 +777,7 @@ launch.state.java=Checking Java version
launch.state.logging_in=Logging in
launch.state.modpack=Downloading required files
launch.state.waiting_launching=Waiting for the game to launch
launch.invalid_java=Invalid Java path, please reset the Java path.
launch.invalid_java=Invalid Java path. Please reset the Java path.
launcher=Launcher
launcher.agreement=ToS and EULA
@@ -791,10 +795,10 @@ launcher.cache_directory.clean=Clear Cache
launcher.cache_directory.choose=Choose cache directory
launcher.cache_directory.default=Default ("%APPDATA%/.minecraft" or "~/.minecraft")
launcher.cache_directory.disabled=Disabled
launcher.cache_directory.invalid=Unable to create cache directory, falling back to default.
launcher.cache_directory.invalid=Failed to create a cache directory, falling back to default.
launcher.contact=Contact Us
launcher.crash=Hello Minecraft! Launcher has encountered a fatal error! Please copy the following log and ask for help on our Discord, QQ group, GitHub or other Minecraft Forum.
launcher.crash.java_internal_error=Hello Minecraft! Launcher has encountered a fatal error due to your Java is broken. Please uninstall your Java, and download a suitable Java <a href="https://bell-sw.com/pages/downloads/#downloads">here</a>.
launcher.crash=Hello Minecraft! Launcher has encountered a fatal error! Please copy the following log and ask for help on our Discord, QQ group, GitHub, or other Minecraft forum.
launcher.crash.java_internal_error=Hello Minecraft! Launcher has encountered a fatal error due to your Java being broken. Please uninstall your Java and download a suitable Java <a href="https://bell-sw.com/pages/downloads/#downloads">here</a>.
launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher has encountered a fatal error! Your launcher is outdated. Please update your launcher!
launcher.update_java=Please update your Java version.
@@ -812,7 +816,7 @@ logwindow.export_dump.no_dependency=Your Java does not contain the dependencies
main_page=Home
message.cancelled=Operation was cancelled
message.cancelled=Operation canceled
message.confirm=Confirm
message.copied=Copied to clipboard
message.default=Default
@@ -827,11 +831,11 @@ message.warning=Warning
modpack=Modpacks
modpack.choose=Choose Modpack
modpack.choose.local=Import From Local File
modpack.choose.local=Import from Local File
modpack.choose.local.detail=You can drag the modpack file here.
modpack.choose.remote=Download From URL
modpack.choose.remote=Download from URL
modpack.choose.remote.detail=A direct download link to the remote modpack file is required.
modpack.choose.repository=Download Modpack From CurseForge or Modrinth
modpack.choose.repository=Download Modpack from CurseForge or Modrinth
modpack.choose.repository.detail=Remember to go back to this page and drop the modpack file here after the modpack is downloaded.
modpack.choose.remote.tooltip=Please enter your modpack URL
modpack.completion=Downloading dependencies
@@ -868,19 +872,19 @@ modpack.origin.mcbbs=MCBBS
modpack.origin.mcbbs.prompt=Post ID
modpack.scan=Parsing Modpack Index
modpack.task.install=Import Modpack
modpack.task.install.error=Unable to identify this modpack. We currently only support Curse, Modrinth, MultiMC, and MCBBS modpacks.
modpack.task.install.error=Failed to identify this modpack. We currently only support Curse, Modrinth, MultiMC, and MCBBS modpacks.
modpack.type.curse=Curse
modpack.type.curse.error=Unable to download dependencies, please try again or use a proxy server.
modpack.type.curse.not_found=Some dependencies are no longer available, please try installing a newer modpack version.
modpack.type.manual.warning=The modpack is manually packaged by the publisher, which may already contain a launcher. It is recommended to try extracting the modpack and running the game with its own launcher. HMCL can still import it, with no guarantee of its usability, still continue?
modpack.type.curse.error=Failed to download dependencies. Please try again or use a proxy server.
modpack.type.curse.not_found=Some dependencies are no longer available. Please try installing a newer modpack version.
modpack.type.manual.warning=The modpack is manually packaged by the publisher, which may already contain a launcher. It is recommended to try extracting the modpack and running the game with its own launcher. HMCL can still import it, with no guarantee of its usability. Still continue?
modpack.type.mcbbs=MCBBS
modpack.type.mcbbs.export=Can be imported by Hello Minecraft! Launcher
modpack.type.modrinth=Modrinth
modpack.type.multimc=MultiMC
modpack.type.multimc.export=Can be imported by Hello Minecraft! Launcher and MultiMC
modpack.type.server=Auto-Update Modpack From Server
modpack.type.server=Auto-Update Modpack from Server
modpack.type.server.export=Allows server owner to update the game instance remotely
modpack.type.server.malformed=Invalid modpack manifest, please refer to the modpack maker to resolving this problem.
modpack.type.server.malformed=Invalid modpack manifest. Please refer to the modpack maker to resolve this problem.
modpack.unsupported=Unsupported modpack format
modpack.update=Updating modpack
modpack.wizard=Modpack Export Guide
@@ -894,7 +898,7 @@ modpack.wizard.step.initialization.exported_version=Game version to export
modpack.wizard.step.initialization.force_update=Force updating the modpack to the latest version (you will need a file-hosting server)
modpack.wizard.step.initialization.include_launcher=Include the launcher
modpack.wizard.step.initialization.save=Export to...
modpack.wizard.step.initialization.warning=Before making a modpack, please make sure the game launches normally, and Minecraft is a release version instead of a snapshot. The launcher will save your download settings.\n\
modpack.wizard.step.initialization.warning=Before making a modpack, please make sure the game launches normally and Minecraft is a release version instead of a snapshot. The launcher will save your download settings.\n\
\n\
Keep in mind that you are not allowed to add mods and resource packs that are explicitly said not to be distributed or put in a modpack.
modpack.wizard.step.initialization.server=Click here for more tutorials for making a server modpack that can be automatically updated.
@@ -988,13 +992,13 @@ mods.check_updates.target_version=Target Version
mods.check_updates.update=Update
mods.choose_mod=Choose mod
mods.curseforge=CurseForge
mods.dependency.embedded=Built-in Pre-mod (Already packaged in the mod file by the author, no need to download separately)
mods.dependency.embedded=Built-in Pre-mod (Already packaged in the mod file by the author. No need to download separately)
mods.dependency.optional=Optional Pre-mod (If missing, the game will run normally, but the mod features may be missing)
mods.dependency.required=Required Pre-mod (Must be downloaded separately, missing may cause the game to fail to launch)
mods.dependency.tool=Required Library (Must be downloaded separately, missing may cause the game to fail to launch)
mods.dependency.required=Required Pre-mod (Must be downloaded separately. Missing may cause the game to fail to launch)
mods.dependency.tool=Required Library (Must be downloaded separately. Missing may cause the game to fail to launch)
mods.dependency.include=Built-in Pre-mod (Already packaged in the mod file by the author, no need to download separately)
mods.dependency.incompatible=Incompatible Mod (Installing these mods at the same time will cause the game to fail to launch)
mods.dependency.broken=Broken Pre-mod (This mod existed before, but it does not exist now, try using another download source.)
mods.dependency.broken=Broken Pre-mod (This mod existed before, but it does not exist now. Try using another download source.)
mods.disable=Disable
mods.download=Mod Download
mods.download.title=Mod Download - %1s
@@ -1007,7 +1011,7 @@ mods.mcmod.page=MCMod Page
mods.mcmod.search=Search in MCMod
mods.modrinth=Modrinth
mods.name=Name
mods.not_modded=You must install a mod loader (Forge, NeoForge, Fabric, Quilt or LiteLoader) first to manage your mods!
mods.not_modded=You must install a mod loader (Forge, NeoForge, Fabric, Quilt, or LiteLoader) first to manage your mods!
mods.restore=Restore
mods.url=Official Page
mods.update_modpack_mod.warning=Updating mods in a modpack can lead to irreparable results, possibly corrupting the modpack so that it cannot launch. Are you sure you want to update?
@@ -1015,8 +1019,8 @@ mods.install=Install
mods.save_as=Save As
nbt.entries=%s entries
nbt.open.failed=Fail to open file
nbt.save.failed=Fail to save file
nbt.open.failed=Failed to open file
nbt.save.failed=Failed to save file
nbt.title=View File - %s
datapack=Datapacks
@@ -1025,7 +1029,7 @@ datapack.choose_datapack=Choose datapack to import
datapack.extension=Datapack
datapack.title=World [%s] - Datapacks
web.failed=Page loading failed
web.failed=Failed to load page
web.open_in_browser=Do you want to open this address in a browser:\n%s
web.view_in_browser=View in browser
@@ -1036,7 +1040,7 @@ world.datapack.1_13=Only Minecraft 1.13 or later supports datapacks.
world.description=%s | Last played on %s | Game Version: %s
world.download=Download World
world.export=Export the World
world.export.title=Choose directory for this exported world
world.export.title=Choose the directory for this exported world
world.export.location=Save As
world.export.wizard=Export World "%s"
world.extension=World Archive
@@ -1044,10 +1048,10 @@ world.game_version=Game Version
world.import.already_exists=This world already exists.
world.import.choose=Choose world archive you want to import
world.import.failed=Failed to import this world: %s
world.import.invalid=Unable to import the save.
world.import.invalid=Failed to parse the world.
world.info.title=World [%s] - Information
world.info.basic=Basic Information
world.info.allow_cheats=Allow Cheats
world.info.allow_cheats=Allow Commands/Cheats
world.info.dimension.the_nether=The Nether
world.info.dimension.the_end=The End
world.info.difficulty=Difficulty
@@ -1082,7 +1086,7 @@ world.show_all=Show All
world.time=h\:mm\:ss a, EEE, MMM d yyyy
profile=Game Directories
profile.already_exists=This name already exists, please use a different name.
profile.already_exists=This name already exists. Please use a different name.
profile.default=Current
profile.home=Minecraft Launcher
profile.instance_directory=Game Directory
@@ -1092,11 +1096,11 @@ profile.name=Name
profile.new=New Directory
profile.title=Game Directories
profile.selected=Selected
profile.use_relative_path=Use relative path for game directory if possible
profile.use_relative_path=Use a relative path for the game directory if possible
repositories.custom=Custom Maven Repository (%s)
repositories.maven_central=Universal (Maven Central)
repositories.tencentcloud_mirror=Mainland China Mirror (Tencent Cloud Maven Repository)
repositories.tencentcloud_mirror=Chinese Mainland Mirror (Tencent Cloud Maven Repository)
repositories.chooser=HMCL requires JavaFX to work.\n\
\n\
Please click "OK" to download JavaFX from the specified repository, or click "Cancel" to exit.\n\
@@ -1107,8 +1111,8 @@ repositories.chooser.title=Choose download source for JavaFX
resourcepack=Resource Packs
search=Search
search.hint.chinese=Supports Chinese and English
search.hint.english=Supports English only
search.hint.chinese=Search in English and Chinese
search.hint.english=Search in English only
search.enter=Enter text here
search.sort=Sort By
search.first_page=First
@@ -1133,12 +1137,12 @@ settings.advanced.custom_commands.hint=The following environment variables are p
\ · $INST_DIR: absolute path of the instance working directory.\n\
\ · $INST_MC_DIR: absolute path of the game directory.\n\
\ · $INST_JAVA: java binary used for launch.\n\
\ · $INST_FORGE: set if Forge installed.\n\
\ · $INST_NEOFORGE: set if NeoForge installed.\n\
\ · $INST_LITELOADER: set if LiteLoader installed.\n\
\ · $INST_OPTIFINE: set if OptiFine installed.\n\
\ · $INST_FABRIC: set if Fabric installed.\n\
\ · $INST_QUILT: set if Quilt installed.
\ · $INST_FORGE: set if Forge is installed.\n\
\ · $INST_NEOFORGE: set if NeoForge is installed.\n\
\ · $INST_LITELOADER: set if LiteLoader is installed.\n\
\ · $INST_OPTIFINE: set if OptiFine is installed.\n\
\ · $INST_FABRIC: set if Fabric is installed.\n\
\ · $INST_QUILT: set if Quilt is installed.
settings.advanced.dont_check_game_completeness=Do not check game integrity
settings.advanced.dont_check_jvm_validity=Do not check Java VM compatibility
settings.advanced.dont_patch_natives=Do not attempt to automatically replace native libraries
@@ -1149,8 +1153,8 @@ settings.advanced.java_permanent_generation_space=PermGen Space
settings.advanced.java_permanent_generation_space.prompt=in MB
settings.advanced.jvm=Java VM Options
settings.advanced.jvm_args=Java VM Arguments
settings.advanced.jvm_args.prompt=\ · If the arguments entered in "Java VM arguments" is the same as the default arguments, it will not be added.\n\
\ · Enter any GC arguments in "Java VM arguments", the G1 argument of the default arguments will be disabled.\n\
settings.advanced.jvm_args.prompt=\ · If the arguments entered in "Java VM arguments" are the same as the default arguments, it will not be added.\n\
\ · Enter any GC arguments in "Java VM arguments", and the G1 argument of the default arguments will be disabled.\n\
\ · Enable "Do not add default Java VM arguments" to launch the game without adding default arguments.
settings.advanced.launcher_visibility.close=Close the launcher after the game launches
settings.advanced.launcher_visibility.hide=Hide the launcher after the game launches
@@ -1166,7 +1170,7 @@ settings.advanced.natives_directory.default=Default
settings.advanced.natives_directory.hint=This option is intended only for users of Apple M1 or other not officially supported platforms. Please do not edit this option unless you know what you are doing.\n\
\n\
Before proceeding, please make sure all libraries (e.g. lwjgl.dll, libopenal.so) are provided in your desired directory.\n\
Note: It is recommended to use a fully English letters path for the specified local library file, otherwise it may lead to game launch failure.
Note: It is recommended to use a fully English-letters path for the specified local library file. Otherwise it may lead to game launch failure.
settings.advanced.no_jvm_args=Do not add default Java VM arguments
settings.advanced.precall_command=Pre-launch Command
settings.advanced.precall_command.prompt=Commands to execute before the game launches
@@ -1181,12 +1185,12 @@ settings.advanced.post_exit_command.prompt=Commands to execute after the game ex
settings.advanced.renderer=Renderer
settings.advanced.renderer.default=OpenGL (Default)
settings.advanced.renderer.d3d12=DirectX 12 (Poor performance and compatibility)
settings.advanced.renderer.llvmpipe=Software (Poor performance and best compatibility)
settings.advanced.renderer.zink=Vulkan (Best performance and poor compatibility)
settings.advanced.renderer.llvmpipe=Software (Poor performance, best compatibility)
settings.advanced.renderer.zink=Vulkan (Best performance, poor compatibility)
settings.advanced.server_ip=Server Address
settings.advanced.server_ip.prompt=Automatically join after launching the game
settings.advanced.use_native_glfw=[Linux Only] Use system GLFW
settings.advanced.use_native_openal=[Linux Only] Use system OpenAL
settings.advanced.use_native_glfw=[Linux/FreeBSD Only] Use System GLFW
settings.advanced.use_native_openal=[Linux/FreeBSD Only] Use System OpenAL
settings.advanced.workaround=Workaround
settings.advanced.workaround.warning=Workaround options are intended only for advanced users. Tweaking with these options may crash the game. Unless you know what you are doing, please do not edit these options.
settings.advanced.wrapper_launcher=Wrapper Command
@@ -1209,7 +1213,7 @@ settings.game.java_directory.version=Specify Java Version
settings.game.java_directory.template=%s (%s)
settings.game.management=Manage
settings.game.working_directory=Working Directory
settings.game.working_directory.choose=Choose working directory
settings.game.working_directory.choose=Choose the working directory
settings.game.working_directory.hint=Enable the "Isolated" option in "Working Directory" to allow the current instance to store its settings, saves, and mods in a separate directory.\n\
\n\
It is recommended to enable this option to avoid mod conflicts, but you will need to move your saves manually.
@@ -1232,7 +1236,7 @@ settings.launcher.general=General
settings.launcher.language=Language (Applies After Restart)
settings.launcher.launcher_log.export=Export Launcher Logs
settings.launcher.launcher_log.reveal=Reveal Logs in Explorer
settings.launcher.launcher_log.export.failed=Unable to export logs.
settings.launcher.launcher_log.export.failed=Failed to export logs.
settings.launcher.launcher_log.export.success=Logs have been exported to "%s".
settings.launcher.log=Logging
settings.launcher.log.font=Font
@@ -1270,11 +1274,11 @@ settings.type.global.manage=Global Settings
settings.type.global.edit=Edit Global Settings
settings.type.special.enable=Enable Instance-specific Settings
settings.type.special.edit=Edit Current Instance Settings
settings.type.special.edit.hint=Current instance "%s" has enabled the "Instance-specific Settings", all options on this page will NOT affect that instance. Click here to edit its own settings.
settings.type.special.edit.hint=Current instance "%s" has enabled the "Instance-specific Settings". All options on this page will NOT affect that instance. Click here to edit its own settings.
sponsor=Donors
sponsor.bmclapi=Downloads are provided by BMCLAPI. Click here for more information.
sponsor.hmcl=Hello Minecraft! Launcher is a FOSS Minecraft launcher which allows users to manage multiple Minecraft instances easily. Click here for more information.
sponsor.bmclapi=Downloads for the Chinese Mainland are provided by BMCLAPI. Click here for more information.
sponsor.hmcl=Hello Minecraft! Launcher is a FOSS Minecraft launcher that allows users to manage multiple Minecraft instances easily. Click here for more information.
system.architecture=Architecture
system.operating_system=Operating System
@@ -1285,40 +1289,34 @@ update=Update
update.accept=Update
update.changelog=Changelog
update.channel.dev=Beta
update.channel.dev.hint=You are currently using a Beta channel build of the launcher, which may include some extra features, but is also sometimes more unstable than the Release channel.\n\
update.channel.dev.hint=You are currently using a Beta channel build of the launcher, which may include some extra features but is also sometimes more unstable than the Release channel.\n\
\n\
If you encounter any bugs or problems, please navigate to "Settings → Feedback" or submit your feedback through the following channels.\n\
\n\
<a href="https://github.com/HMCL-dev/HMCL">GitHub</a> <a href="https://discord.gg/jVvC7HfM6U">Discord</a> <a href="https://docs.hmcl.net/groups.html">QQ Group</a>\n\
\n\
<a href="hmcl://hide-announcement">Click Here to Hide This Tooltip for the Current Channel</a>
If you encounter any bugs or problems, please navigate to <a href="hmcl://settings/feedback">Settings → Feedback</a> page to submit your feedback.
update.channel.dev.title=Beta Channel Notice
update.channel.nightly=Nightly
update.channel.nightly.hint=You are currently using a Nightly channel build of the launcher, which may include some extra features, but is also always more unstable than the other channels.\n\
update.channel.nightly.hint=You are currently using a Nightly channel build of the launcher, which may include some extra features but is also always more unstable than the other channels.\n\
\n\
If you encounter any bugs or problems, please navigate to "Settings → Feedback" or submit your feedback through the following channels.\n\
\n\
<a href="https://github.com/HMCL-dev/HMCL">GitHub</a> <a href="https://discord.gg/jVvC7HfM6U">Discord</a> <a href="https://docs.hmcl.net/groups.html">QQ Group</a>
If you encounter any bugs or problems, please navigate to <a href="hmcl://settings/feedback">Settings → Feedback</a> page to submit your feedback.
update.channel.nightly.title=Nightly Channel Notice
update.channel.stable=Release
update.checking=Checking for Updates
update.failed=Unable to update
update.failed=Failed to update
update.found=Update Available!
update.newest_version=Latest version: %s
update.bubble.title=Update Available: %s
update.bubble.subtitle=Click here to update
update.note=Beta & Nightly channels may have more features or fixes, but is also come with more potential problems.
update.note=Beta and Nightly channels may have more features or fixes, but they also come with more potential problems.
update.latest=This is the latest version
update.no_browser=Cannot open in system browser. But we copied the link to your clipboard and you can open it manually.
update.no_browser=Cannot open in system browser. But we copied the link to your clipboard, and you can open it manually.
update.tooltip=Update
version=Games
version.name=Instance Name
version.cannot_read=Unable to parse the game instance, installation cannot continue.
version.cannot_read=Failed to parse the game instance, installation cannot continue.
version.empty=No Instances
version.empty.add=Add new instance
version.empty.launch=No instances, you can install one in "Download → New Game".
version.empty.hint=There are no Minecraft instances here. You can try switching to another game directory or click here to download one.
version.empty.launch=No instances. You can install one in "Download → New Game".
version.empty.hint=There are no Minecraft instances here. You can try switching to another game directory or clicking here to download one.
version.game.old=Historical
version.game.release=Release
version.game.releases=Releases
@@ -1328,7 +1326,7 @@ version.launch=Launch Game
version.launch.test=Test Launch
version.switch=Switch Instance
version.launch_script=Export Launch Script
version.launch_script.failed=Unable to export launch script.
version.launch_script.failed=Failed to export launch script.
version.launch_script.save=Export Launch Script
version.launch_script.success=Exported launch script as %s.
version.manage=All Instances
@@ -1349,7 +1347,7 @@ version.manage.remove_assets=Delete All Assets
version.manage.remove_libraries=Delete All Libraries
version.manage.rename=Rename Instance
version.manage.rename.message=Enter New Instance Name
version.manage.rename.fail=Unable to rename the instance, some files might be in use or the name contains an invalid character.
version.manage.rename.fail=Failed to rename the instance, some files might be in use, or the name contains an invalid character.
version.settings=Settings
version.update=Update Modpack
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2023 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2024 huangyuhui <huanghongxun2008@126.com> 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
@@ -23,25 +23,29 @@ about=Acerca de
about.copyright=Copyright
about.copyright.statement=Copyright © 2024 huangyuhui.
about.author=Autor
about.author.statement=@huanghongxun en bilibili
about.author.statement=bilibili @huanghongxun
about.claim=EULA
about.claim.statement=Haz clic en este enlace para ver el texto completo.
about.claim.statement=Haga clic en este enlace para ver el texto completo.
about.dependency=Bibliotecas de terceros
about.legal=Reconocimiento legal
about.thanks_to=Gracias a
about.thanks_to.bangbang93.statement=Por proporcionar la API de descarga de BMCLAPI, por favor considere hacer una donación.
about.thanks_to.bangbang93.statement=Por proporcionar el espejo de descarga de BMCLAPI, por favor considere hacer una donación!
about.thanks_to.burningtnt.statement=Aportar mucho apoyo técnico a HMCL.
about.thanks_to.contributors=Todos los colaboradores en GitHub
about.thanks_to.contributors.statement=Sin la impresionante comunidad de código abierto, Hello Minecraft! Launcher no habría llegado tan lejos.
about.thanks_to.contributors.statement=Sin la impresionante comunidad de código abierto, HMCL no habría llegado tan lejos.
about.thanks_to.gamerteam.statement=Por proporcionar la imagen de fondo por defecto.
about.thanks_to.glavo.statement=Aportar mucho apoyo técnico a HMCL.
about.thanks_to.glavo.statement=Responsable del mantenimiento de HMCL.
about.thanks_to.zekerzhayard.statement=Aportar mucho apoyo técnico a HMCL.
about.thanks_to.zkitefly.statement=Aportar mucho apoyo técnico a HMCL.
about.thanks_to.mcmod=mcmod.cn
about.thanks_to.mcmod.statement=Por facilitar las traducciones al chino y el wiki de varios mods.
about.thanks_to.zkitefly.statement=Responsable del mantenimiento de la documentación de HMCL.
about.thanks_to.mcbbs=MCBBS (Foro Chino Minecraft)
about.thanks_to.mcbbs.statement=Por proporcionar el espejo de descarga de mcbbs.net para los usuarios de China continental. (Ya no disponible)
about.thanks_to.mcmod=MCMod (mcmod.cn)
about.thanks_to.mcmod.statement=Por proporcionar las traducciones al chino simplificado y la wiki de varios mods.
about.thanks_to.red_lnn.statement=Por proporcionar la imagen de fondo por defecto.
about.thanks_to.shulkersakura.statement=Por proporcionar el logotipo de HMCL.
about.thanks_to.users=Miembros del grupo de usuarios de HMCL
about.thanks_to.users.statement=Gracias por las donaciones, los informes de errores, etc.
about.thanks_to.yushijinhun.statement=Por proporcionar soporte relacionado con authlib-injector.
about.thanks_to.yushijinhun.statement=Por proporcionar el soporte relacionado con authlib-injector.
about.open_source=Código abierto
about.open_source.statement=GPL v3 (https://github.com/HMCL-dev/HMCL)
@@ -148,6 +152,7 @@ assets.index.malformed=Los archivos de índice de los activos descargados estaba
button.cancel=Cancelar
button.change_source=Cambiar fuente de descarga
button.clear=Limpiar
button.copy_and_exit=Copiar y salir
button.delete=Borrar
button.edit=Editar
button.install=Instalar
@@ -156,17 +161,21 @@ button.no=No
button.ok=Aceptar
button.refresh=Refrescar
button.remove=Eliminar
button.remove.confirm=¿Está seguro de querer eliminarlo definitivamente? Esta acción no se puede deshacer.
button.remove.confirm=¿Estás seguro de que deseas eliminarlo de forma permanente? ¡Esta acción no se puede deshacer!
button.retry=Reintentar
button.save=Guardar
button.save_as=Guardar como
button.select_all=Seleccionar todo
button.view=Vista
button.yes=Sí
chat=Chat de grupo
color.recent=Recomendado
color.custom=Color personalizado
crash.NoClassDefFound=Por favor, verifique la integridad de este software, o intente actualizar su versión de Java.
crash.user_fault=El launcher se ha bloqueado debido a un entorno Java o de sistema corrupto. Por favor, asegúrese de que su Java o sistema operativo está instalado correctamente.
crash.NoClassDefFound=Por favor, verifique la integridad de este software, o intente actualizar su Java.
crash.user_fault=El lanzador se ha bloqueado debido a que Java o el entorno del sistema están dañados. Por favor, asegúrese de que su Java o sistema operativo está instalado correctamente.
curse.category.0=Todos
@@ -316,7 +325,7 @@ download.javafx.prepare=Preparando la descarga
exception.access_denied=HMCL no puede acceder al archivo %s, puede estar bloqueado por otro proceso.\n\
\n\
Para los usuarios de Windows, puede abrir el 'Monitor de Recursos' para comprobar si otro proceso lo está utilizando actualmente. Si es así, puede intentarlo de nuevo después de cerrar ese proceso.\
Para los usuarios de Windows, puede abrir el 'Monitor de Recursos' para comprobar si otro proceso lo está utilizando actualmente. Si es así, puede intentarlo de nuevo después de cerrar ese proceso.\n\
Si no es así, comprueba si tu cuenta tiene suficientes privilegios para acceder a él.
exception.artifact_malformed=No se puede verificar la integridad de los archivos descargados .
exception.ssl_handshake=No se puede establecer una conexión SSL debido a que faltan certificados SSL en la instalación actual de Java. Puede intentar ejecutar HMCL en otra versión de Java y luego volver a intentarlo.
@@ -333,7 +342,7 @@ Por favor, intente cambiar a versiones de Java como Oracle Java 8 que tiene Java
fatal.javafx.missing=No se encontró un entorno JavaFX.\n\
Si está utilizando Java 11 o superior, por favor, descargue Oracle JRE 8 (java.com), o instale BellSoft Liberica Full JRE (bell-sw.com/pages/downloads).\n\
O, si está utilizando distribuciones de OpenJDK, asegúrese de que tiene incluido OpenJFX.
fatal.config_loading_failure=No se pueden cargar los archivos de configuración.\nPara macOS, intente colocar HMCL en un lugar con permiso que no sea "Escritorio", "Descargas" y "Documentos" y vuelva a intentarlo.
fatal.config_loading_failure=No se pueden cargar los archivos de configuración.\nPara macOS, intente colocar HMCL en un lugar con permiso que no sea "Escritorio", "Descargas" y "Documentos" y vuelva a intentarlo.\n\
¡Por favor, asegúrese de que "Hello Minecraft! Launcher" tiene acceso de lectura y escritura a "%s" y a los archivos que contiene.
fatal.migration_requires_manual_reboot=Hello Minecraft! Launcher ha sido actualizado. Por favor, reinicie el launcher.
fatal.apply_update_failure=Lo sentimos, pero Hello Minecraft! Launcher no puede actualizarse.\n\
@@ -345,8 +354,13 @@ fatal.illegal_char=Su ruta de usuario contiene un carácter ilegal '\=', por lo
Por ejemplo, no podrá utilizar authlib-injector o cambiar el skin de su cuenta offline.
feedback=Comentarios
feedback.channel=Canal de comentarios
feedback.discord=Discord
feedback.discord.statement=¡Únete a nuestra comunidad de Discord!
feedback.discord.statement=¡Únase a nuestro servidor Discord!
feedback.github=GitHub Issues
feedback.github.statement=Envíe una propuesta en GitHub.
feedback.qq_group=Grupo QQ de usuarios de HMCL
feedback.qq_group.statement=¡Únase a nuestro grupo QQ de usuarios!
file=Archivo
@@ -374,7 +388,7 @@ game.crash.reason.bootstrap_failed=El juego se ha bloqueado debido al mod %1$s.\
\n\
Puedes intentar borrarlo o actualizarlo.
game.crash.reason.config=El juego se ha bloqueado porque un mod %1$s no puede analizar su archivo de configuración %2$s.
game.crash.reason.debug_crash=El juego se ha bloqueado porque lo has activado manualmente.
game.crash.reason.debug_crash=El juego se ha bloqueado porque lo has activado manualmente.\n\
\n\
Entonces, probablemente sabes por qué.
game.crash.reason.mixin_apply_mod_failed=El juego se ha bloqueado porque Mixin no puede aplicar el mod %1$s, no se puede continuar.\n\
@@ -431,7 +445,7 @@ game.crash.reason.loading_crashed_fabric=El juego se ha bloqueado debido al mod
Puedes intentar borrarlo o actualizarlo.
game.crash.reason.memory_exceeded=El juego se ha bloqueado debido a que se ha asignado demasiada memoria para un pequeño archivo de paginación.\n\
\n\
Puede intentar desactivar la opción de asignación automática de memoria en la configuración y ajustar el valor hasta que el juego se inicie.
Puede intentar desactivar la opción de asignación automática de memoria en la configuración y ajustar el valor hasta que el juego se inicie.\n\
También puede tratar de aumentar el tamaño del archivo de paginación en la configuración del sistema.
game.crash.reason.mod=El juego se ha bloqueado debido al mod %1$s.\n\
\n\
@@ -470,22 +484,19 @@ game.crash.reason.mod_resolution_mod_version.any=%1$s (Cualquier versión)
game.crash.reason.forge_repeat_installation=El juego actual no puede continuar ejecutándose debido a una instalación duplicada de Forge. <a href="https://github.com/HMCL-dev/HMCL/issues/1880">Este es un problema conocido</a>\nSe recomienda cargar los comentarios del registro en GitHub para que podamos encontrar más pistas y arreglar esta pregunta. \nActualmente puede ir a la instalación automática para desinstalar Forge y volver a instalarlo.
game.crash.reason.optifine_repeat_installation=El juego actual no puede seguir ejecutándose debido a la instalación repetida de OptiFine. \nElimine OptiFine de la carpeta Mod o vaya a Gestión de juegos-Instalación automática para desinstalar OptiFine que se instala automáticamente.
game.crash.reason.modmixin_failure=El juego actual no puede continuar ejecutándose debido a algunas fallas en la inyección de mods. \nEsto generalmente significa que el mod tiene un error o no es compatible con el entorno actual. \nPuede consultar el registro para ver si hay un mod incorrecto.
game.crash.reason.file_or_content_verification_failed=El juego actual tiene un problema porque fallaron algunos archivos o la verificación de contenido. \nIntente eliminar esta versión (incluidas las modificaciones) y vuelva a descargarla, o intente usar un proxy cuando vuelva a descargar, etc.
game.crash.reason.mod_repeat_installation=El juego actual tiene múltiples Mods idénticos instalados repetidamente, y cada Mod solo puede aparecer una vez. Elimina los Mods repetidos y luego inicia el juego.
game.crash.reason.forge_error=Forge puede haber proporcionado un mensaje de error.\nPuede ver el registro y realizar las acciones correspondientes de acuerdo con la información de registro en el informe de errores.\nSi no ve un mensaje de error, puede consultar el informe de errores para saber cómo ocurrió el error.\n%1$s
game.crash.reason.mod_solution0=El juego actual no puede seguir ejecutándose debido a algunos problemas de modificación.\nPuede consultar el registro para ver si hay un mod incorrecto.
game.crash.reason.mod_profile_causes_game_crash=El juego actual no puede seguir ejecutándose debido a un problema con el perfil de mod.\nPuede consultar el registro del mod defectuoso y su archivo de configuración.
game.crash.reason.fabric_reports_an_error_and_gives_a_solution=Forge puede haber dado un mensaje de error.\nPuede ver el registro y realizar las acciones correspondientes de acuerdo con la información de registro en el informe de errores.\nSi no ve un mensaje de error, puede consultar el informe de errores para saber cómo ocurrió el error.
game.crash.reason.mod_resolution0=El juego actual no puede seguir ejecutándose debido a algunos problemas de modificación.\nPuede consultar el registro para ver si hay un mod incorrecto.
game.crash.reason.java_version_is_too_high=El juego actual se bloqueó porque la versión de Java es demasiado alta y no puede seguir ejecutándose.\nCambie a una versión anterior de Java en la pestaña Java Path de Configuración global del juego o Configuración específica del juego antes de iniciar el juego.\nSi no es así, puede descargarlo desde <a href="https://www.java.com/download/">java.com (Java8)</a> o <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java17)</a> y otras plataformas para descargar e instalar una (reinicie el iniciador después de la instalación).
game.crash.reason.mod_name=El juego actual no puede continuar ejecutándose debido a un problema con el nombre del archivo mod. El nombre del archivo de\nMod solo debe usar mayúsculas y minúsculas (Aa ~ Zz), números (0 ~ 9), líneas horizontales (-), subrayado (_) y puntos (.) en toda la mitad del inglés.\n Por favor, vaya a la carpeta mod para agregar un carácter de Cumplimiento anterior a todos los nombres de archivo mod que no cumplan.
game.crash.reason.incomplete_forge_installation=O jogo atual não pode continuar devido a uma instalação incompleta do Forge / NeoForge.\nDesinstale e reinstale o Forge / NeoForge em Configurações de versão - Instalação automática.
game.crash.reason.modlauncher_8=El juego se ha bloqueado porque tu versión actual de Forge no es compatible con tu instalación de Java. Por favor, intente actualizar Forge, o intente utilizar Java 8u312/11.0.13/17.0.1 o versiones anteriores.\n\
\n\
8u312 y anteriores\:\n\
https://oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html
https://oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html\n\
\n\
11.0.13 y anteriores\:\n\
https://oracle.com/java/technologies/javase/jdk11-archive-downloads.html
https://oracle.com/java/technologies/javase/jdk11-archive-downloads.html\n\
\n\
17.0.1 y anteriores\:\n\
https://oracle.com/java/technologies/javase/jdk17-archive-downloads.html
@@ -494,21 +505,21 @@ game.crash.reason.no_class_def_found_error=El juego no puede ejecutarse debido a
A su instancia de juego le falta %1$s, esto puede deberse a que falta un mod, a que hay un mod incompatible instalado o a que algunos archivos pueden estar dañados.\n\
\n\
Puede que tengas que reinstalar el juego y todos los mods o pedir ayuda a alguien.
game.crash.reason.no_sethod_error=El juego no puede ejecutarse debido a un código incompleto.\n\
game.crash.reason.no_such_method_error=El juego no puede ejecutarse debido a un código incompleto.\n\
\n\
Es posible que a su instancia de juego le falte un mod, que haya instalado un mod incompatible o que algunos archivos estén dañados.\n\
\n\
Puede que tengas que reinstalar el juego y todos los mods o pedir ayuda a alguien.
game.crash.reason.opengl_not_supported=El juego se ha bloqueado porque OpenGL no es compatible con su controlador de gráficos.\n\
\n\
Si está transmitiendo el juego a través de Internet o utilizando un entorno de escritorio remoto, por favor, intente jugar el juego en su entorno local.
Si está transmitiendo el juego a través de Internet o utilizando un entorno de escritorio remoto, por favor, intente jugar el juego en su entorno local.\n\
O bien, puede intentar actualizar su controlador a la última versión y volver a intentarlo.\n\
\n\
Si tu ordenador tiene una tarjeta gráfica discreta, por favor, asegúrate de que el juego la está utilizando para el renderizado. Si el problema persiste, considera la posibilidad de adquirir una nueva tarjeta gráfica o un nuevo ordenador.
game.crash.reason.openj9=El juego no puede ejecutarse en una máquina virtual OpenJ9. Por favor, cambia a una VM Java Hotspot en la configuración del juego y vuelve a ejecutar el juego. Si no tienes una, puedes descargar una en línea.
game.crash.reason.out_of_memory=El juego se ha bloqueado porque se ha quedado sin memoria.\n\
\n\
Esto puede deberse a que no hay suficiente memoria disponible, o a que hay demasiados mods instalados. Puedes intentar solucionarlo aumentando la memoria asignada en la configuración del juego.
Esto puede deberse a que no hay suficiente memoria disponible, o a que hay demasiados mods instalados. Puedes intentar solucionarlo aumentando la memoria asignada en la configuración del juego.\n\
Si sigues encontrando estos problemas, es posible que necesites una mejor computadora.
game.crash.reason.resolution_too_high=El juego se ha bloqueado porque estás utilizando un resource packs cuya resolución de textura es demasiado alta.\n\
\n\
@@ -533,11 +544,6 @@ game.crash.reason.unsatisfied_link_error=No se puede iniciar Minecraft porque fa
Si ha modificado la configuración de la biblioteca nativa, por favor, asegúrese de que estas bibliotecas existen. O, por favor, intente iniciar de nuevo después de revertir a los valores predeterminados.\n\
Si no lo ha hecho, por favor, compruebe si le faltan mods de dependencia.\n\
De lo contrario, si usted cree que esto es causado por HMCL, por favor, comentarios a nosotros.
game.crash.reason.failed_to_load_a_library=Failed to load a library.\n\
\n\
Si ha modificado la configuración de la biblioteca nativa, por favor, asegúrese de que estas bibliotecas existen. O, por favor, intente iniciar de nuevo después de revertir a los valores predeterminados.\n\
Si no lo ha hecho, por favor, compruebe si le faltan mods de dependencia.\n\
De lo contrario, si usted cree que esto es causado por HMCL, por favor, comentarios a nosotros.
game.crash.title=Juego interrumpido
game.directory=Ruta del juego
game.version=Versión del juego
@@ -592,6 +598,36 @@ install.new_game.malformed=Nombre no válido
install.select=Seleccione una operación
install.success=Instalado con éxito.
java.add=Añadir Java
java.add.failed=Este Java no es válido o es incompatible con la plataforma actual.
java.disable=Deshabilitar este Java
java.disable.confirm=¿Está seguro de que desea desactivar este Java?
java.disabled.management=Java desactivado
java.disabled.management.remove=Eliminar este Java de la lista
java.disabled.management.restore=Activar este Java
java.download=Descargar Java
java.download.load_list.failed=Error al cargar la lista de versiones
java.download.more=Más distribuciones de Java
java.download.prompt=Elija la versión de Java que desea descargar:
java.download.distribution=Distribución
java.download.version=Versión
java.download.packageType=Tipo de paquete
java.management=Gestión Java
java.info.architecture=Arquitectura
java.info.vendor=Proveedor
java.info.version=Versión
java.info.disco.distribution=Distribución
java.install=Instalar Java
java.install.archive=Fuente Path
java.install.failed.exists=Este nombre ya tiene dueño
java.install.failed.invalid=Este archivo no es un paquete de instalación de Java válido, por lo que no se puede instalar.
java.install.failed.unsupported_platform=Este Java no es compatible con la plataforma actual, por lo que no puede instalarse.
java.install.name=Nombre
java.install.warning.invalid_character=Carácter ilegal en el nombre
java.reveal=Revelar el directorio de Java
java.uninstall=Desinstalar Java
java.uninstall.confirm=¿Está seguro de que desea desinstalar este Java? ¡Esta acción no se puede deshacer!
lang=Español
lang.default=Usar idioma del sistema
@@ -615,8 +651,6 @@ launch.advice.too_large_memory_for_32bit=Has asignado un tamaño de memoria mayo
launch.advice.vanilla_linux_java_8=Minecraft 1.12.2 o inferior sólo admite Java 8 para la plataforma Linux x86-64, porque las versiones posteriores no pueden cargar las bibliotecas nativas de 32 bits como liblwjgl.so\n\
\n\
Por favor, descárguelo de java.com, o instale OpenJDK 8.
launch.advice.vanilla_x86=Minecraft actualmente no proporciona soporte oficial para arquitecturas distintas de x86 o x86-64.\n\
Puedes intentar descargar la librería nativa de tu plataforma y especificar su ruta, luego vuelve a intentarlo.
launch.advice.vanilla_x86.translation=Minecraft no proporciona actualmente soporte oficial para arquitecturas distintas de x86 y x86-64.\n\
Por favor, instale Java para x86-64 para jugar a Minecraft a través del entorno de traducción Rosetta, o descargue sus bibliotecas nativas correspondientes y especifique su ruta.
launch.failed=No se puede ejecutar
@@ -654,7 +688,7 @@ launcher.background.translucent=Translúcido
launcher.cache_directory=Directorio de la caché
launcher.cache_directory.clean=Borrar caché
launcher.cache_directory.choose=Elegir el directorio de la caché
launcher.cache_directory.default=Por defecto (%AppData%/.minecraft o ~/.minecraft)
launcher.cache_directory.default=Por defecto (%APPDATA%/.minecraft o ~/.minecraft)
launcher.cache_directory.disabled=Desactivado
launcher.cache_directory.invalid=No se ha podido crear el directorio de la caché, volviendo a los valores por defecto.
launcher.contact=Contacta con nosotros
@@ -733,7 +767,6 @@ modpack.scan=Análisis del índice de modpacks
modpack.task.install=Instalar Modpack
modpack.task.install.error=No se ha podido identificar este modpack. Actualmente sólo soportamos los modpacks Curse, Modrinth, MultiMC y MCBBS.
modpack.type.curse=Curse
modpack.type.curse.tolerable_error=No se han podido descargar las dependencias, puedes intentar continuar la descarga ejecutando esta instancia del juego.
modpack.type.curse.error=No se han podido descargar las dependencias de CurseForge, inténtalo de nuevo o utiliza una conexión proxy.
modpack.type.curse.not_found=Algunas dependencias ya no están disponibles, por favor intenta instalar una versión más reciente del modpack.
modpack.type.manual.warning=Este archivo contiene una copia completa de una instancia de Minecraft. La mayoría de las veces, sólo tienes que descomprimirlo y ejecutar el juego usando su launcher incorporado. Pero, HMCL todavía puede importarlo, sin garantía de su utilidad, ¿aún continúa?
@@ -741,7 +774,7 @@ modpack.type.mcbbs=Tipo MCBBS
modpack.type.mcbbs.export=Puede ser importado por ¡Hello Minecraft! Launcher
modpack.type.modrinth=Modrinth
modpack.type.multimc=MultiMC
¡modpack.type.multimc.export=Puede ser importado por Hello Minecraft! Launcher y MultiMC
modpack.type.multimc.export=Puede ser importado por Hello Minecraft! Launcher y MultiMC
modpack.type.server=Actualización automática del modpack desde el servidor
modpack.type.server.export=Permite al propietario del servidor actualizar la instancia del juego de forma remota
modpack.type.server.malformed=Manifiesto de modpack inválido, por favor, consulte al creador del modpack del servidor para solucionar este problema.
@@ -758,7 +791,7 @@ modpack.wizard.step.initialization.exported_version=Versión del juego a exporta
modpack.wizard.step.initialization.force_update=Forzar la actualización del modpack a la última versión (necesitarás un servicio de alojamiento de archivos)
modpack.wizard.step.initialization.include_launcher=Incluir el launcher
modpack.wizard.step.initialization.save=Exportar a...
modpack.wizard.step.initialization.warning=Antes de crear un modpack, por favor asegúrate de que el juego se ejecuta, y que es una versión de lanzamiento en lugar de una versión instantánea. El launcher guardará su configuración de descarga.
modpack.wizard.step.initialization.warning=Antes de crear un modpack, por favor asegúrate de que el juego se ejecuta, y que es una versión de lanzamiento en lugar de una versión instantánea. El launcher guardará su configuración de descarga.\n\
\n\
Ten en cuenta que no se te permite añadir mods y resource packs que se digan explícitamente que no se pueden distribuir o poner en un modpack.
modpack.wizard.step.initialization.server=Haga clic aquí para ver más tutoriales para hacer un modpack de servidor que se pueda actualizar automáticamente.
@@ -937,8 +970,8 @@ settings.advanced.post_exit_command=Comando post-salida
settings.advanced.post_exit_command.prompt=Comandos a ejecutar tras la salida del juego
settings.advanced.server_ip=Dirección del servidor
settings.advanced.server_ip.prompt=Entrar automáticamente después de ejecutar el juego
settings.advanced.use_native_glfw=[Sólo Linux] Utilizar GLFW nativo
settings.advanced.use_native_openal=[Sólo Linux] Utilizar OpenAL nativo
settings.advanced.use_native_glfw=[Sólo Linux/FreeBSD] Utilizar GLFW nativo
settings.advanced.use_native_openal=[Sólo Linux/FreeBSD] Utilizar OpenAL nativo
settings.advanced.workaround=Métodos alternativos
settings.advanced.workaround.warning=Éstas opciones están pensadas sólo para usuarios expertos. Jugar con estas opciones puede romper el juego. A menos que sepas lo que estás haciendo, por favor no modifiques estas opciones.
settings.advanced.wrapper_launcher=Wrapper Launcher
@@ -1022,8 +1055,8 @@ settings.type.special.edit=Editar ajustes de la instancia actual
settings.type.special.edit.hint=La instancia actual [%s] tiene activada la configuración por instancia, todas las opciones de esta página NO afectarán a esa instancia. Haga clic aquí para modificar sus propias opciones.
sponsor=Donantes
sponsor.bmclapi=Las descargas son proporcionadas por BMCLAPI. Haz clic aquí para obtener más información.
sponsor.hmcl=¡Hello Minecraft! Launcher es un launcher FOSS de Minecraft que permite a los usuarios gestionar múltiples instancias de Minecraft fácilmente. Usted puede donar a nosotros en Afdian para apoyar nuestro alojamiento de archivos y el desarrollo del proyecto. Haga clic aquí para obtener más información.
sponsor.bmclapi=Las descargas de China continental son proporcionadas por BMCLAPI. Haga clic aquí para obtener más información.
sponsor.hmcl=Hello Minecraft! Launcher es un launcher FOSS de Minecraft que permite a los usuarios gestionar múltiples instancias de Minecraft fácilmente. Haga clic aquí para obtener más información.
system.architecture=Arquitectura
system.operating_system=Sistema operativo
@@ -1033,15 +1066,13 @@ update.accept=Actualizar
update.changelog=Registro de cambios
update.channel.dev=Beta
update.channel.dev.hint=Actualmente está utilizando una versión beta del launcher, que puede incluir algunas características adicionales, pero también es más inestable que las versiones de lanzamiento.\n\
\n\
Si encuentra algún error o problema, puede ir a la <a href="hmcl://settings/feedback">página de comentarios</a> para informar de ello, o bien para decírnoslo en nuestro <a href="https://discord.gg/jVvC7HfM6U">Discord</a> o en la comunidad <a href="https://docs.hmcl.net/groups.html">QQ</a>.\n\
\n\
<a href="hmcl://hide-announcement">Haga clic aquí</a> para ocultar el recordatorio para la versión de prueba actual.
\n\
Si encuentra algún error o problema, puede ir a la <a href="hmcl://settings/feedback">página de comentarios</a> para informar de ello.
update.channel.dev.title=Aviso de versión beta
update.channel.nightly=Nocturna
update.channel.nightly.hint=Estás utilizando una versión nocturna del launcher, que puede incluir algunas características adicionales, pero también es siempre más inestable que las otras versiones.\n\
\n\
Si encuentra algún error o problema, puede ir a la <a href="hmcl://settings/feedback">página de comentarios</a> para informar de ello, o bien para decírnoslo en nuestro <a href="https://discord.gg/jVvC7HfM6U">Discord</a> o en la comunidad <a href="https://docs.hmcl.net/groups.html">QQ</a> community.
\n\
Si encuentra algún error o problema, puede ir a la <a href="hmcl://settings/feedback">página de comentarios</a> para informar de ello.
update.channel.nightly.title=Aviso de versión nocturna
update.channel.stable=Estable
update.checking=Buscando actualizaciones
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2023 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2024 huangyuhui <huanghongxun2008@126.com> 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
@@ -17,31 +17,36 @@
#
# Contributors: zhixuan2333
about=About
about=について
about.copyright=著作権
about.copyright.statement=Copyright © 2024 huangyuhui。
about.author=Author
about.author.statement=bilibili : @huanghongxun
about.copyright.statement=Copyright © 2024 huangyuhui
about.author=著者
about.author.statement=bilibili @huanghongxun
about.claim=EULA
about.claim.statement=テキスト全体のリンクをクリックします。
about.dependency=Dependencies
about.claim.statement=全文はこのリンクをクリック
about.dependency=依存関係
about.legal=法的承認
about.thanks_to=Thanks to
about.thanks_to.bangbang93.statement=BMCLAPIダウンロードソースプロバイダー。
about.thanks_to.contributors=問題、プルリクエストなどを介してこのプロジェクトに参加したすべての貢献者。
about.thanks_to.contributors.statement=Hello Minecraftをサポートしてくれたオープンソースコミュニティに感謝します!ランチャー
about.thanks_to.gamerteam.statement=デフォルトの背景画像プロバイダー。
about.thanks_to.glavo.statement=HMCLに多くのテクニカルサポートを提供
about.thanks_to=感謝します…
about.thanks_to.bangbang93.statement=BMCLAPIダウンロードミラープロバイダー。寄付をご検討ください!
about.thanks_to.burningtnt.statement=HMCLに多くのテクニカルサポートを提供
about.thanks_to.contributors=GitHubのすべての貢献者
about.thanks_to.contributors.statement=HMCLをサポートしてくれたオープンソースコミュニティに感謝する
about.thanks_to.gamerteam.statement=デフォルトの背景画像プロバイダー
about.thanks_to.glavo.statement=HMCLのメンテナ
about.thanks_to.zekerzhayard.statement=HMCLに多くのテクニカルサポートを提供
about.thanks_to.zkitefly.statement=HMCLに多くのテクニカルサポートを提供。
about.thanks_to.mcmod=mcmod.cn
about.thanks_to.mcmod.statement=Mod中国語の名前翻訳プロバイダー。
about.thanks_to.red_lnn.statement=デフォルトの背景画像プロバイダー。
about.thanks_to.zkitefly.statement=HMCLドキュメントメンテナ
about.thanks_to.mcbbs=MCBBS (Minecraft中国語フォーラム)
about.thanks_to.mcbbs.statement=中国本土ユーザー向けのmcbbs.netダウンロードミラープロバイダー(もう利用できません)
about.thanks_to.mcmod=MCMod (mcmod.cn)
about.thanks_to.mcmod.statement=様々なMODの簡体字中国語名前翻訳とウィキを提供する
about.thanks_to.red_lnn.statement=デフォルトの背景画像プロバイダー
about.thanks_to.shulkersakura.statement=HMCLロゴプロバイダー
about.thanks_to.users=HMCLユーザーグループのメンバー
about.thanks_to.users.statement=寄付、バグレポートなどに感謝します。
about.thanks_to.yushijinhun.statement=authlib-インジェクターのサポート
about.thanks_to.users.statement=寄付、バグレポートなどに感謝します
about.thanks_to.yushijinhun.statement=authlib-injector関連のサポートを提供する
about.open_source=オープンソース
about.open_source.statement=GPL v3(https://github.com/HMCL-dev/HMCL/)
about.open_source.statement=GPL v3 (https://github.com/HMCL-dev/HMCL)
account=アカウント
account.cape=マント
@@ -135,6 +140,7 @@ assets.index.malformed=アセットインデックスの形式が正しくあり
button.cancel=キャンセル
button.change_source=ダウンロードソースの変更
button.clear=クリア
button.copy_and_exit=コピーして終了
button.delete=削除
button.edit=編集
button.install=インストール
@@ -143,19 +149,23 @@ button.no=いいえ
button.ok=OK
button.refresh=更新
button.remove=削除
button.remove.confirm=削除してもよろしいですか?この操作をロールバックすることはできません!
button.remove.confirm=本当に完全に削除しますか?この操作は元に戻せません!
button.retry=リトライ
button.save=保存
button.save_as=名前を付けて保存
button.select_all=すべて選択
button.view=読む
button.yes=はい
chat=グループチャット
color.recent=推奨
color.custom=カスタムカラー
crash.NoClassDefFound=「HelloMinecraft!Launcher」ソフトウェアが破損していないことを確認してください。
crash.user_fault=OSまたはJava環境が正しくインストールされていない可能性があり、クラッシュする可能性があります。Javaランタイム環境またはコンピュータを確認してください。
crash.NoClassDefFound=このソフトウェアの整合性を確認するか、Javaの更新をお試しください。
crash.user_fault=JavaまたはOSの環境が壊れているため、ランチャーがクラッシュしました。JavaまたはOSが正しくインストールされているかご確認ください。
curse.category.0=すべて
curse.category.0=全て
# https://addons-ecs.forgesvc.net/api/v2/category/section/4471
curse.category.4474=Sci-Fi
@@ -313,9 +323,15 @@ fatal.apply_update_failure=ごめんなさい、Hello Minecraft! Launcher 何か
fatal.samba=If you are trying to run HMCL in a shared folder by Samba, HMCL may not working, please try updating your Java or running HMCL in a local folder.
fatal.illegal_char=ユーザーフォルダーのパスに不正な文字'='が含まれています, ログインアカウントやオフラインログインではスキンの変更ができなくなり。
feedback=フィードバック
feedback.channel=フィードバックチャンネル
feedback.discord=Discord
feedback.discord.statement=チャットに参加しよう!
feedback.discord.statement=Discordサーバーに参加してください!
feedback.github=GitHub Issues
feedback.github.statement=GitHubで問題を送信します。
feedback.qq_group=HMCLユーザーQQグループ
feedback.qq_group.statement=ユーザーQQグループに参加してください!
file=ファイル
@@ -343,12 +359,9 @@ game.crash.reason.entity=エンティティが原因でゲームを実行でき
game.crash.reason.fabric_version_0_12=Fabric 0.12以降は、現在インストールされているmodと互換性がありません。ファブリックを0.11.7にダウングレードする必要があります。
game.crash.reason.fabric_warnings=Fabricはいくつかの警告を出します:\n%1$s
game.crash.reason.modmixin_failure=mod インジェクションの失敗により、現在のゲームを続行できません。\nこれは通常、MOD にバグがあるか、現在の環境と互換性がないことを意味します。\n間違った mod のログを確認できます。
game.crash.reason.file_or_content_verification_failed=一部のファイルまたはコンテンツの検証に失敗したため、現在のゲームに問題があります。\nこのバージョン (mod を含む) を削除して再ダウンロードするか、再ダウンロード時にプロキシを使用するなどしてください。
game.crash.reason.mod_repeat_installation=現在のゲームには複数の同一の Mod が繰り返しインストールされており、各 Mod は 1 回しか表示できません。ゲームを開始する前に繰り返しの Mod を削除してください。
game.crash.reason.forge_error=Forge がエラー メッセージを表示した可能性があります。 \nログを表示し、エラー レポートのログ情報に従って対応するアクションを実行できます。 \nエラー メッセージが表示されない場合は、エラー レポートをチェックして、エラーがどのように発生したかを知ることができます。\n%1$s
game.crash.reason.mod_resolution0=mod の問題により、現在のゲームを続行できません。 \n間違った mod のログを確認できます。
game.crash.reason.mod_profile_causes_game_crash=mod プロファイルに問題があるため、現在のゲームを続行できません。 \n障害のある mod とその構成ファイルのログを確認できます。
game.crash.reason.fabric_reports_an_error_and_gives_a_solution=Forge がエラー メッセージを表示した可能性があります。 \nログを表示し、エラー レポートのログ情報に従って対応するアクションを実行できます。 \nエラー メッセージが表示されない場合は、エラー レポートをチェックして、エラーがどのように発生したかを知ることができます。
game.crash.reason.java_version_is_too_high=Java のバージョンが高すぎて実行を継続できないため、現在のゲームがクラッシュしました。 \nゲームを起動する前に、グローバル ゲーム設定またはゲーム固有の設定の Java パス タブで Java の以前のバージョンに切り替えてください。 \nそうでない場合は、<a href="https://www.java.com/download/">java.com (Java8)</a> または <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java17)</a> およびその他のプラットフォームをダウンロードしてインストールします (インストール後にランチャーを再起動します)。
game.crash.reason.mod_name=現在のゲームはModファイル名の問題で続行できません。\nModファイル名は、英文の全半角の大文字と小文字(Aa ~ Zz)、数字(0 ~ 9)、横線(-)、アンダースコア(_)、点(.)のみを使用してください。\n上記のコンプライアンス文字をModフォルダに追加してください。
game.crash.reason.incomplete_forge_installation=Forge / NeoForge のインストールが不完全なため、現在のゲームを続行できません。\nバージョン設定 - 自動インストールで Forge / NeoForge をアンインストールしてから再インストールしてください。
@@ -393,7 +406,6 @@ game.crash.reason.stacktrace=不明。[ログ]ボタンをクリックすると
game.crash.reason.too_old_java=Java仮想マシンのバージョンが低すぎるため、ゲームを実行できません。\nゲーム設定でJava仮想マシンの新しいバージョン(%1$s)に切り替えて、ゲームを再起動する必要があります。そうでない場合は、オンラインでダウンロードできます。
game.crash.reason.unknown=不明。「ログ」ボタンをクリックすると詳細を確認できます。
game.crash.reason.unsatisfied_link_error=必要なネイティブライブラリがないため、ゲームを実行できません。\n不足しているネイティブライブラリ:%1$s。\nゲーム設定でネイティブライブラリパスオプションを変更した場合は、元に戻すことをお勧めします。標準モードに切り替えます。\nすでに標準モードになっている場合は、不足しているネイティブライブラリがmodまたはゲームに属しているかどうかを確認してください。HMCLが原因であることが確実な場合は、フィードバックをお送りください。\nネイティブライブラリパスを本当にカスタマイズする必要がある場合は、ゲームに必要なすべてのネイティブライブラリをディレクトリに配置する必要があります。
game.crash.reason.failed_to_load_a_library=ネイティブ ライブラリのロードに失敗したため、ゲームを実行できません。\nゲーム設定でネイティブライブラリパスオプションを変更した場合は、元に戻すことをお勧めします。標準モードに切り替えます。\nすでに標準モードになっている場合は、不足しているネイティブライブラリがmodまたはゲームに属しているかどうかを確認してください。HMCLが原因であることが確実な場合は、フィードバックをお送りください。\nネイティブライブラリパスを本当にカスタマイズする必要がある場合は、ゲームに必要なすべてのネイティブライブラリをディレクトリに配置する必要があります。
game.crash.title=ゲームがクラッシュしました
game.directory=ゲームディレクトリ
game.version=ゲームバージョン
@@ -448,6 +460,36 @@ install.new_game.malformed=無効な名前
install.select=操作を選択します
install.success=正常にインストールされました
java.add=Javaの追加
java.add.failed=このJavaは無効であるか、現在のプラットフォームと互換性がない。
java.disable=無効化
java.disable.confirm=本当にこのJavaを無効にしますか?
java.disabled.management=無効なJava
java.disabled.management.remove=このJavaをリストから削除する
java.disabled.management.restore=有効化
java.download=Javaをダウンロード
java.download.load_list.failed=バージョンリストの読み込みに失敗しました
java.download.more=その他のJavaディストリビューション
java.download.prompt=ダウンロードしたいJavaのバージョンを選択してください:
java.download.distribution=配布の種類
java.download.version=バージョン
java.download.packageType=パッケージの種類
java.management=Javaの管理
java.info.architecture=アーキテクチャ
java.info.vendor=発行元
java.info.version=バージョン
java.info.disco.distribution=配布の種類
java.install=Javaのインストール
java.install.archive=場所
java.install.failed.exists=この名前はすでに使用されている
java.install.failed.invalid=このアーカイブは有効なJavaインストール・パッケージではないため、インストールできません。
java.install.failed.unsupported_platform=このJavaは現在のプラットフォームと互換性がないため、インストールできません。
java.install.name=名前
java.install.warning.invalid_character=名前に不正な文字が含まれています
java.reveal=Javaディレクトリを表示する
java.uninstall=このJavaをアンインストールする
java.uninstall.confirm=本当にこのJavaをアンインストールしますか?この操作は元に戻せません!
lang=日本語
lang.default=システム言語を使用する
@@ -460,8 +502,8 @@ launch.advice.forge2760_liteloader=Forge 2760以降はLiteLoaderと互換性が
launch.advice.forge28_2_2_optifine=Forge28.2.2以降のバージョンはOptiFineと互換性がありません。Forgeを28.2.1以前のバージョンにダウングレードすることを検討してください。
launch.advice.java8_1_13=Minecraft 1.13以降は、Java8以降でのみ実行できます。
launch.advice.java8_51_1_13=Minecraft 1.13は、1.8.0_51より前のJava8でクラッシュする可能性があります。最新バージョンのJava8をインストールしてください。
launch.advice.java9=Java9以降のバージョンのJavaでMinecraft1.12以前を起動することはできません。
ゲームを高速化するには、launch.advice.newer_java=Java8をお勧めします。多くのMinecraft1.12以降、およびほとんどのModには、Java8が必要です。
launch.advice.java9=Java9以降のバージョンのJavaでMinecraft1.12以前を起動することはできません。ゲームを高速化するには、Java8をお勧めします。
launch.advice.newer_java=多くのMinecraft1.12以降、およびほとんどのModには、Java8が必要です。
launch.advice.not_enough_space=割り当てたメモリが多すぎます。物理メモリサイズが%dMBであるため、ゲームがクラッシュする可能性があります。
launch.advice.too_large_memory_for_32bit=32ビットJavaランタイム環境が原因で、割り当てたメモリが多すぎるため、ゲームがクラッシュする可能性があります。32ビットシステムの最大メモリ容量は1024MBです。
launch.advice.vanilla_linux_java_8=Linux x86-64の場合、Minecraft1.12.2以下はJava8でのみ実行できます。\nJava9以降のバージョンでは、liblwjgl.soなどの32ビットネイティブライブラリをロードできません。
@@ -499,7 +541,7 @@ launcher.background.translucent=半透明
launcher.cache_directory=キャッシュ用のディレクトリ
launcher.cache_directory.clean=クリアランス
launcher.cache_directory.choose=キャッシュするディレクトリを選択します
launcher.cache_directory.default=標準(%AppData%/.minecraft または ~/.minecraft)
launcher.cache_directory.default=標準(%APPDATA%/.minecraft または ~/.minecraft)
launcher.cache_directory.disabled=無効(常にゲームパスを使用する)
launcher.cache_directory.invalid=無効なディレクトリ。デフォルト設定の復元。
launcher.contact=お問い合わせ
@@ -574,8 +616,6 @@ modpack.scan=このmodpackをスキャンしています
modpack.task.install=Modpackのインポート
modpack.task.install.error=このmodpackファイルは認識できません。CurseおよびMultiMCmodpackのみがサポートされています。
modpack.type.curse=Curse
modpack.type.curse.completion=Cursemodpackに関連するファイルをインストールします
modpack.type.curse.tolerable_error=このmodpackのすべてのファイルのダウンロードを完了できません。対応するゲームバージョンを開始するときに、ダウンロードを再試行できます。ネットワークの問題により、数回再試行する場合があります。
modpack.type.curse.error=このmodpackをインストールできません。再試行してください。
modpack.type.curse.not_found=必要なリソースの一部が欠落しているため、ダウンロードできませんでした。最新バージョンまたは他のmodpackを検討してください。
modpack.type.manual.warning=このmodpackをインポートする代わりに、おそらくこのmodpackファイルを直接解凍する必要があります。そして、バンドルされたランチャーを使用してゲームを起動します。このmodpackは、ランチャーによってエクスポートされるのではなく、.minecraftディレクトリを圧縮することによって手動で作成されます。HMCLはこのmodpackのインポートを試みることができます、続行しますか?
@@ -761,8 +801,8 @@ settings.advanced.post_exit_command=終了後のコマンド
settings.advanced.post_exit_command.prompt=ゲーム終了後に実行されます
settings.advanced.server_ip=サーバーアドレス
settings.advanced.server_ip.prompt=ゲームの起動時にサーバーに参加する
settings.advanced.use_native_glfw=システムGLFWを使用する
settings.advanced.use_native_openal=システムOpenALを使用する
settings.advanced.use_native_glfw=[Linux/FreeBSDのみ]システムGLFWを使用する
settings.advanced.use_native_openal=[Linux/FreeBSDのみ]システムOpenALを使用する
settings.advanced.workaround=デバッグ用オプション
settings.advanced.workaround.warning=デバッグオプションはプロフェッショナルのみ使用可能です。デバッグオプションにより、ゲームが起動しない場合があります。これらのオプションは、ご自分が何をしているのかが分からない限り、変更しないでください。
settings.advanced.wrapper_launcher=パッキングオーダー
@@ -843,8 +883,8 @@ settings.type.special.edit=現在のゲーム設定を構成します
settings.type.special.edit.hint=現在のゲームバージョン %s で特殊な設定が有効になっているため、現在のページのオプションはそのゲームバージョンに適用されません。リンクをクリックして、現在のゲーム設定を構成します。
sponsor=寄付
sponsor.bmclapi=ダウンロードサービスはBMCLAPIによって提供されます。詳細については、ここをクリックしてください。
sponsor.hmcl=こんにちはマインクラフト! Launcherは、無料のオープンソースのMinecraftランチャーであり、ユーザーは複数の個別のMinecraftインストールを簡単に管理できます。私たちはAfdianを使用して、ホスティングとプロジェクト開発の費用を引き続き支払います。詳細については、ここをクリックしてください。
sponsor.bmclapi=中国本土向けのダウンロードサービスはBMCLAPIによって提供されています。詳細については、ここをクリックしてください。
sponsor.hmcl=Hello Minecraft! Launcherは、無料のオープンソースのMinecraftランチャーであり、ユーザーは複数の個別のMinecraftインストールを簡単に管理できます。詳細については、ここをクリックしてください。
system.architecture=Arch
system.operating_system=OS
@@ -853,15 +893,14 @@ update=更新
update.accept=更新
update.changelog=変更
update.channel.dev=ベータ
update.channel.dev.hint=ベータ版を使用しています。ベータ版には、リリースバージョンと比較していくつかの追加機能が含まれている可能性があり、テストにのみ使用されます。\n\
ベータ版は不安定なはずです!\n\
問題が発生した場合は、<a href="hmcl://settings/feedback">フィードバックページ</a>にアクセスして報告するか、チャット <a href="https://discord.gg/jVvC7HfM6U">Discord</a>または<a href="https://docs.hmcl.net/groups.html">QQ</a>で問題を報告します。\n\n\
現在のテスト版のヒントを非表示にするには、<a href="hmcl://hide-announcement">ここをクリックしてください</a>。
update.channel.dev.hint=ベータ版を使用しています。ベータ版には、リリースバージョンと比較していくつかの追加機能が含まれている可能性があり、テストにのみ使用されます。ベータ版は不安定なはずです!\n\
\n\
問題が発生した場合は、<a href="hmcl://settings/feedback">フィードバックページ</a>にアクセスして報告してください。
update.channel.dev.title=ベータ版のヒント
update.channel.nightly=アルファ
update.channel.nightly.hint=アルファ版を使用しています。これには、ベータ版およびリリース版と比較していくつかの追加機能が含まれている可能性があり、テストにのみ使用されます。\n\
アルファ版は不安定です!\n\
問題が発生した場合は、<a href="hmcl://settings/feedback">フィードバックページ</a>にアクセスして報告するか、チャット <a href="https://discord.gg/jVvC7HfM6U">Discord</a>で問題を報告します。
update.channel.nightly.hint=アルファ版を使用しています。これには、ベータ版およびリリース版と比較していくつかの追加機能が含まれている可能性があり、テストにのみ使用されます。アルファ版は不安定です!\n\
\n\
問題が発生した場合は、<a href="hmcl://settings/feedback">フィードバックページ</a>にアクセスして報告してください。
update.channel.nightly.title=アルファ版のヒント
update.channel.stable=リリース
update.checking=更新の確認
@@ -1,44 +1,47 @@
#
# Hello Minecraft! Launcher
# Авторские права (C) 2023 huangyuhui <huanghongxun2008@126.com> и участников
# Copyright (C) 2024 huangyuhui <huanghongxun2008@126.com> and contributors
#
# Эта программа является бесплатным программным обеспечением:
# вы можете распространять и/или изменять её на условиях GNU
# General Public License, опубликованной Free Software Foundation,
# либо 3й версией лицензии, либо (по вашему выбору) любой версией выше.
# 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.
#
# Эта программа распространяется в надежде, что она окажется полезной,
# но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; даже без подразумеваемых гарантий
# ТОВАРНОЙ ПРИГОДНОСТИ или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ.
# Подробности смотрите в Стандартной общественной лицензии GNU.
# 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.
#
# Вместе с этой программой вы должны были получить копию GNU
# General Public License. Если нет, смотрите <https://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Соавторы: vanja-san
#
# Contributors: vanja-san
about=О лаунчере
about.copyright=Авторские права
about.copyright.statement=Авторские права © 2024 huangyuhui.
about.author=Автор
about.author.statement=bilibili: @huanghongxun
about.author.statement=bilibili @huanghongxun
about.claim=EULA
about.claim.statement=Кликните на ссылку, чтобы увидеть весь текст.
about.dependency=Зависимости
about.legal=Юридическое подтверждение
about.thanks_to=Отдельная благодарность
about.thanks_to.bangbang93.statement=За предоставление API скачивания BMCLAPI. Рассмотрите возможность пожертвования.
about.thanks_to.bangbang93.statement=За предоставление зеркала загрузки BMCLAPI, пожалуйста, подумайте о пожертвовании!
about.thanks_to.burningtnt.statement=Оказал большую техническую поддержку HMCL.
about.thanks_to.contributors=Всем участникам на GitHub
about.thanks_to.contributors.statement=Без потрясающего сообщества с открытым исходным кодом, Hello Minecraft! Launcher не смог бы добраться так далеко.
about.thanks_to.contributors.statement=Без потрясающего сообщества с открытым исходным кодом, HMCL не смог бы добраться так далеко.
about.thanks_to.gamerteam.statement=За предоставление фонового изображения.
about.thanks_to.glavo.statement=Оказал большую техническую поддержку HMCL.
about.thanks_to.glavo.statement=Отвечает за поддержание HMCL.
about.thanks_to.zekerzhayard.statement=Оказал большую техническую поддержку HMCL.
about.thanks_to.zkitefly.statement=Оказал большую техническую поддержку HMCL.
about.thanks_to.mcmod=mcmod.cn
about.thanks_to.mcmod.statement=За предоставление перевода на китайский и вики для различных модов.
about.thanks_to.zkitefly.statement=Отвечает за поддержание документации HMCL.
about.thanks_to.mcbbs=MCBBS (Китайский форум Minecraft)
about.thanks_to.mcbbs.statement=За предоставление зеркала загрузки mcbbs.net для пользователей материкового Китая. (Больше недоступно)
about.thanks_to.mcmod=MCMod (mcmod.cn)
about.thanks_to.mcmod.statement=За предоставление упрощенного китайского перевода и вики для различных модов.
about.thanks_to.red_lnn.statement=За предоставление фонового изображения.
about.thanks_to.shulkersakura.statement=За предоставление логотипа для HMCL.
about.thanks_to.users=Членам группы пользователей HMCL
about.thanks_to.users.statement=Спасибо за пожертвования, отчёты об ошибках и так далее.
about.thanks_to.yushijinhun.statement=За предоставление поддержки, связанной с authlib-injector.
@@ -157,8 +160,11 @@ button.retry=Повторить снова
button.save=Сохранить
button.save_as=Сохранить как
button.select_all=Выбрать все
button.view=Просмотреть
button.yes=Да
chat=Групповой чат
color.recent=Рекомендуемые
color.custom=Пользовательский цвет
@@ -336,8 +342,13 @@ fatal.samba=Если вы пытаетесь запустить лаунчер
fatal.illegal_char=Недопустимый символ '=' в пути к папке пользователя. Лаунчер может работать, но некоторые функции не будут работать.\nВы не сможете использовать аккаунт authlib-injector или изменить офлайн скин.
feedback=Обратная связь
feedback.channel=Канал обратной связи
feedback.discord=Discord
feedback.discord.statement=Присоединиться!
feedback.discord.statement=Добро пожаловать присоединиться к нашему Discord.
feedback.github=Проблемы GitHub
feedback.github.statement=Отправьте проблему на GitHub.
feedback.qq_group=Группа QQ пользователя HMCL
feedback.qq_group.statement=Добро пожаловать присоединиться к нашей группе QQ!
file=Файл
@@ -365,13 +376,10 @@ game.crash.reason.fabric_version_0_12=Fabric 0.12 (и выше) несовмес
game.crash.reason.mixin_apply_mod_failed=Текущая игра не может продолжать работать из-за невозможности применения мода %1$s с помощью Mixin.\nВы можете попробовать удалить или обновить этот мод, чтобы решить проблему.
game.crash.reason.fabric_warnings=Предупреждения от Fabric:\n%1$s
game.crash.reason.modmixin_failure=Текущая игра не может продолжать работать из-за некоторых сбоев внедрения модов.\nОбычно это означает, что мод содержит ошибку или несовместим с текущей средой.\nВы можете проверить журнал на наличие неправильного мода.
game.crash.reason.file_or_content_verification_failed=В текущей игре возникла проблема, поскольку не удалось проверить некоторые файлы или содержимое.\nПожалуйста, попробуйте удалить эту версию (включая моды) и загрузить заново, или попробуйте использовать прокси при повторной загрузке и т. д.
game.crash.reason.mod_repeat_installation=В текущей игре неоднократно установлено несколько одинаковых модов, и каждый мод может появиться только один раз. Пожалуйста, удалите повторяющиеся моды перед запуском игры.
game.crash.reason.need_jdk11=Текущая игра не может продолжать работать из-за неподходящей версии виртуальной машины Java.\nВам необходимо загрузить и установить Java 11, а также установить версию Java, начинающуюся с 11, в глобальных (конкретных) настройках игры.
game.crash.reason.forge_error=Возможно, Forge предоставил сообщение об ошибке.\nВы можете просмотреть журнал и выполнить соответствующие действия в соответствии с информацией журнала в отчете об ошибках.\nЕсли вы не видите сообщения об ошибке, вы можете просмотреть отчет об ошибке, чтобы узнать, как она возникла.\n%1$s
game.crash.reason.mod_resolution0=Текущая игра не может продолжать работать из-за некоторых проблем с модом.\nВы можете проверить журнал на наличие неправильного мода.
game.crash.reason.mod_profile_causes_game_crash=Текущая игра не может продолжать работать из-за проблемы с профилем мода.\nВы можете проверить журнал на наличие неисправного мода и его конфигурационного файла.
game.crash.reason.fabric_reports_an_error_and_gives_a_solution=Forge мог выдать сообщение об ошибке.\nВы можете просмотреть журнал и выполнить соответствующие действия в соответствии с информацией журнала в отчете об ошибках.\nЕсли вы не видите сообщения об ошибке, вы можете просмотреть отчет об ошибке, чтобы узнать, как она возникла.
game.crash.reason.java_version_is_too_high=Текущая игра аварийно завершилась из-за того, что версия Java слишком высока и не может продолжать работать.\nПеред запуском игры переключитесь на более раннюю версию Java на вкладке "Путь к Java" в глобальных настройках игры или в настройках игры.\nЕсли нет, вы можете загрузить его с <a href="https://www.java.com/download/">java.com (Java8)</a> или <a href="https://bell- sw.com/pages/downloads">BellSoft Liberica Full JRE (Java17)</a> и другие платформы, чтобы загрузить и установить ее (перезапустите программу запуска после установки).
game.crash.reason.mod_name=Текущая игра не может продолжать работать из - за проблем с именем файла Mod. Имя файла\nMod должно быть использовано только в английском языке в полном углу с большими буквами (Aa ~ Zz), цифрами (0 ~ 9), горизонтальными линиями (-), подчеркнутыми (_) и точками (.) .\nПожалуйста, добавьте символ соответствия в папку Mod для всех несовместимых имен файлов Mod.
game.crash.reason.incomplete_forge_installation=Текущая игра не может быть продолжена из-за незавершенной установки Forge / NeoForge.\nУдалите и переустановите Forge / NeoForge в настройках версии - Автоматическая установка.
@@ -416,7 +424,6 @@ game.crash.reason.stacktrace=Неизвестно. Вы можете просм
game.crash.reason.too_old_java=Невозможно запустить игру из-за того, что версия виртуальной машины Java слишком низкая.\nYou need to switch to a newer version (%1$s) of Java virtual machine in the game settings and restart the game. If not, you can download it online.
game.crash.reason.unknown=Неизвестно. Вы можете просмотреть подробности, кликнув на кнопку «Журналы».
game.crash.reason.unsatisfied_link_error=Невозможно запустить игру из-за того, что отсутствуют необходимые встроенные библиотеки.\nОтсутствующая нативная библиотека: %1$s.\nЕсли в настройках игры вы изменили параметр пути к нативной библиотеке, лучше переключиться обратно в стандартный режим.\nЕсли это уже стандартный режим, проверьте, принадлежит ли отсутствующая нативная библиотека моду или игре. Если вы уверены, что это произошло по вине HMCL, вы можете написать нам через обратную связь.\nЕсли вам действительно нужно настроить путь к нативным библиотекам, вы должны поместить в каталог все нативные библиотеки, которые требуются игре.
game.crash.reason.failed_to_load_a_library=Не удалось запустить игру, так как не удалось загрузить встроенную библиотеку.\nЕсли в настройках игры вы изменили параметр пути к нативной библиотеке, лучше переключиться обратно в стандартный режим.\nЕсли это уже стандартный режим, проверьте, принадлежит ли отсутствующая нативная библиотека моду или игре. Если вы уверены, что это произошло по вине HMCL, вы можете написать нам через обратную связь.\nЕсли вам действительно нужно настроить путь к нативным библиотекам, вы должны поместить в каталог все нативные библиотеки, которые требуются игре.
game.crash.title=Игра вылетела
game.directory=Путь игры
game.version=Версия игры
@@ -471,6 +478,36 @@ install.new_game.malformed=Недопустимое имя
install.select=Выберите операцию
install.success=Успешно установлено.
java.add=Добавить Java
java.add.failed=Этот Java недопустим или несовместим с текущей платформой.
java.disable=Отключить Java
java.disable.confirm=Вы уверены, что хотите отключить эту Java?
java.disabled.management=Отключенная Java
java.disabled.management.remove=Удалить эту Java из списка
java.disabled.management.restore=Включить эту Java
java.download=Скачать Java
java.download.load_list.failed=Не удалось загрузить список версий
java.download.more=Больше дистрибутивов Java
java.download.prompt=Выберите версию Java, которую вы хотите загрузить:
java.download.distribution=Дистрибуция
java.download.version=Версия
java.download.packageType=Тип упаковки
java.management=Управление Java
java.info.architecture=Архитектура
java.info.vendor=Поставщик
java.info.version=Версия
java.info.disco.distribution=Дистрибуция
java.install=Установите Java
java.install.archive=Расположение
java.install.failed.exists=Это имя уже используется
java.install.failed.invalid=Этот архив не является допустимым установочным пакетом Java, поэтому его установка невозможна.
java.install.failed.unsupported_platform=Эта Java несовместима с текущей платформой, поэтому ее невозможно установить.
java.install.name=Название
java.install.warning.invalid_character=Неправильный символ в названии
java.reveal=Откройте каталог Java
java.uninstall=Удалить Java
java.uninstall.confirm=Вы уверены, что хотите удалить эту Java? Это действие нельзя отменить!
lang=Русский
lang.default=Использовать язык системы
@@ -526,7 +563,7 @@ launcher.background.translucent=Полупрозрачный
launcher.cache_directory=Папка с кэшем
launcher.cache_directory.clean=Очистить кэш
launcher.cache_directory.choose=Выберите папку для кэша
launcher.cache_directory.default=По умолчанию (%AppData%/.minecraft или ~/.minecraft)
launcher.cache_directory.default=По умолчанию (%APPDATA%/.minecraft или ~/.minecraft)
launcher.cache_directory.disabled=Отключено
launcher.cache_directory.invalid=Не удаётся создать папку для кэша, возвращаем к значению по умолчанию.
launcher.contact=Связаться с нами
@@ -602,8 +639,6 @@ modpack.scan=Разбор индекса модпака
modpack.task.install=Установить модпак
modpack.task.install.error=Не удаётся идентифицировать этот модпак. Поддерживаются только модпаки Curse, Modrinth, MultiMC и MCBBS.
modpack.type.curse=Curse
modpack.type.curse.completion=Установите файлы, связанные с модпаком Curse
modpack.type.curse.tolerable_error=Мы не можем завершить скачивание всех файлов этого модпака. Вы можете повторить скачивание при запуске соответствующей версии игры. Вы можете повторить попытку несколько раз из-за проблем с сетью.
modpack.type.curse.error=Невозможно установить этот модпак. Повторите ещё раз.
modpack.type.curse.not_found=Некоторые из необходимых ресурсов отсутствуют и поэтому не могут быть загружены. Скачайте последнюю версию или другие модпаки.
modpack.type.manual.warning=Возможно, вам нужно напрямую распаковать файл этого модпака, а не импортировать его. И запустите игру с помощью прилагаемого лаунчера. Этот модпак создаётся вручную путем сжатия директории .minecraft, а не экспортируется лаунчером. HMCL может попытаться импортировать этот модпак, продолжать?
@@ -708,7 +743,7 @@ world.import.failed=Не удаётся импортировать этот ми
world.import.invalid=Не удаётся разобрать сохранение.
world.info.title=Сведения о мире %s
world.info.basic=Основные сведения
world.info.allow_cheats=Разрешить читы
world.info.allow_cheats=Разрешить команды/читы
world.info.dimension.the_nether=Нижний мир
world.info.dimension.the_end=Край
world.info.difficulty=Сложность
@@ -831,8 +866,8 @@ settings.advanced.post_exit_command=Команда после выхода
settings.advanced.post_exit_command.prompt=Команды, которые необходимо выполнить после выхода из игры
settings.advanced.server_ip=Адрес сервера
settings.advanced.server_ip.prompt=Присоединяться к серверу при запуске игры
settings.advanced.use_native_glfw=Использовать системный GLFW
settings.advanced.use_native_openal=Использовать системный OpenAL
settings.advanced.use_native_glfw=[Только для Linux/FreeBSD] Использовать системный GLFW
settings.advanced.use_native_openal=[Только для Linux/FreeBSD] Использовать системный OpenAL
settings.advanced.workaround=Обходные пути
settings.advanced.workaround.warning=Варианты обхода предназначены только для опытных пользователей. Изменение этих параметров может привести к вылету игры. Если не знаете, что делаете, то не изменяйте эти параметры.
settings.advanced.wrapper_launcher=Команда-оболочка
@@ -917,8 +952,8 @@ settings.type.special.edit=Изменить настройки текущего
settings.type.special.edit.hint=В текущем экземпляре [%s] включены раздельные настройки для экземпляров, параметры на этой странице НЕ повлияют на этот экземпляр. Нажмите здесь, чтобы изменить раздельные параметры.
sponsor=Спонсоры
sponsor.bmclapi=Скачивание предоставляется BMCLAPI. Нажмите здесь для получения подробностей.
sponsor.hmcl=Hello Minecraft! Launcher — лаунчер Minecraft с открытым исходным кодом, который позволяет пользователям легко управлять несколькими экземплярами Minecraft. Пожертвуйте нам на Afdian для поддержки нашего файлового хостинга и развития проекта. Для получения подробностей нажмите здесь.
sponsor.bmclapi=Загрузки для материкового Китая предоставляются BMCLAPI. Нажмите здесь для получения подробностей.
sponsor.hmcl=Hello Minecraft! Launcher — лаунчер Minecraft с открытым исходным кодом, который позволяет пользователям легко управлять несколькими экземплярами Minecraft. Для получения подробностей нажмите здесь.
system.architecture=Архитектура
system.operating_system=Операционная система
@@ -927,15 +962,14 @@ update=Обновление
update.accept=Обновить
update.changelog=Изменения
update.channel.dev=Бета
update.channel.dev.hint=Вы используете бета-версию, которая может включать некоторые дополнительные функции по сравнению с релизной версией, используемой только для тестирования.\n\
Бета-версия может быть нестабильной!\n\
Если вы встретили какие-то проблемы, вы можете зайти на <a href="hmcl://settings/feedback">страницу обратной связи</a>, чтобы сообщить о них, или присоединиться к чату <a href="https://discord.gg/jVvC7HfM6U">Discord</a> или <a href="https://docs.hmcl.net/groups.html">QQ</a>, чтобы сообщить о проблемах.\n\n\
<a href="hmcl://hide-announcement">Нажмите здесь</a>, чтобы скрыть подсказку для текущей тестовой версии.
update.channel.dev.hint=Вы используете бета-версию, которая может включать некоторые дополнительные функции по сравнению с релизной версией, используемой только для тестирования. Бета-версия может быть нестабильной!\n\
\n\
Если вы встретили какие-то проблемы, вы можете зайти на <a href="hmcl://settings/feedback">страницу обратной связи</a>.
update.channel.dev.title=Подсказки для бета-версии
update.channel.nightly=Альфа
update.channel.nightly.hint=Вы используете альфа-версию, которая может включать некоторые дополнительные функциональные возможности по сравнению с бета-версией и версией релиза, используемой только для тестирования.\n\
Альфа-версия может быть нестабильной!\n\
Если вы встретили какие-то проблемы, вы можете зайти на <a href="hmcl://settings/feedback">страницу обратной связи</a>, чтобы сообщить о них, или присоединиться к чату <a href="https://discord.gg/jVvC7HfM6U">Discord</a> или <a href="https://docs.hmcl.net/groups.html">QQ</a>, чтобы сообщить о проблемах.
update.channel.nightly.hint=Вы используете альфа-версию, которая может включать некоторые дополнительные функциональные возможности по сравнению с бета-версией и версией релиза, используемой только для тестирования. Альфа-версия может быть нестабильной!\n\
\n\
Если вы встретили какие-то проблемы, вы можете зайти на <a href="hmcl://settings/feedback">страницу обратной связи</a>.
update.channel.nightly.title=Подсказки для альфа-версии
update.channel.stable=Релиз
update.checking=Проверка наличия обновлений
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2023 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2024 huangyuhui <huanghongxun2008@126.com> 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
@@ -17,6 +17,7 @@
#
# Contributors: pan93412
about=關於
about.copyright=著作權
about.copyright.statement=著作權所有 © 2024 huangyuhui
@@ -64,7 +65,7 @@ account.failed.injector_download_failure=無法下載 authlib-injector,請檢
account.failed.invalid_credentials=你的使用者名稱或密碼錯誤,或者登入次數過多被暫時禁止登入,請稍後再試。
account.failed.invalid_password=密碼無效
account.failed.invalid_token=請嘗試登出並重新輸入密碼登入。
account.failed.migration=你的帳戶需要遷移至 Microsoft 帳戶。如果你已經遷移,你需要使用 Microsoft 方式登入遷移後的帳戶。
account.failed.migration=你的帳戶需要遷移至 Microsoft 帳戶。如果你已經遷移,你需要使用遷移後的 Microsoft 帳戶登入。
account.failed.no_character=該帳戶沒有角色。
account.failed.server_disconnected=無法訪問登入伺服器,帳戶資訊重新整理失敗。\n\
你可以選取「再次重新整理帳戶」重新嘗試。\n\
@@ -97,11 +98,11 @@ account.copy_uuid=複製該帳戶的 UUID
account.methods=登入方式
account.methods.authlib_injector=authlib-injector 登入
account.methods.microsoft=Microsoft 帳戶
account.methods.microsoft.birth=如何修改帳戶出生日期
account.methods.microsoft.deauthorize=解除帳戶授權
account.methods.microsoft.birth=如何變更帳戶出生日期
account.methods.microsoft.deauthorize=移除應用存取權
account.methods.microsoft.close_page=已完成 Microsoft 帳戶授權,接下來啟動器還需要完成其餘登入步驟。你現在可以關閉本頁面了。
account.methods.microsoft.error.add_family=由於你未滿 18 歲,你的帳戶必須被加入到家庭中才能登入遊戲。你也可以點擊上方連結更改你的帳戶的出生日期,使年齡滿 18 歲以上以繼續登入。
account.methods.microsoft.error.add_family_probably=請檢查你的帳戶設定,如果你未滿 18 歲,你的帳戶必須被加入到家庭中才能登入遊戲。你也可以點擊上方連結更改你的帳戶的出生日期,使年齡滿 18 歲以上以繼續登入。
account.methods.microsoft.error.add_family=由於你未滿 18 歲,你的帳戶必須被加入到家庭中才能登入遊戲。你也可以點擊上方「編輯帳戶配置檔」更改你的帳戶出生日期,使年齡滿 18 歲以上以繼續登入。
account.methods.microsoft.error.add_family_probably=請檢查你的帳戶設定,如果你未滿 18 歲,你的帳戶必須被加入到家庭中才能登入遊戲。你也可以點擊上方「編輯帳戶配置檔」更改你的帳戶出生日期,使年齡滿 18 歲以上以繼續登入。
account.methods.microsoft.error.country_unavailable=你所在的國家或地區不受 Xbox Live 的支援。
account.methods.microsoft.error.missing_xbox_account=你的 Microsoft 帳戶尚未關聯 Xbox 帳戶,你必須先建立 Xbox 帳戶,才能登入遊戲。
account.methods.microsoft.error.no_character=該帳戶未包含 Minecraft: Java 版購買記錄。\n若已購買,則可能未建立遊戲檔案,請點擊上方連結建立。
@@ -111,17 +112,17 @@ account.methods.microsoft.logging_in=登入中……
account.methods.microsoft.makegameidsettings=建立檔案 / 編輯檔案名稱
account.methods.microsoft.hint=請點擊「登入」按鈕,稍後複製此處顯示的代碼,在打開的登入網頁中完成登入過程。\n\
\n\
如果登入 Microsoft 帳戶的令牌洩露,可點擊下方連結解除授權,然後等待令牌過期。\n\
如果登入 Microsoft 帳戶的令牌洩露,可點擊下方「移除應用存取權」,然後等待令牌過期。\n\
\n\
如遇到問題,你可以點擊右上角幫助按鈕進行求助。
account.methods.microsoft.manual=你的代碼為 <b>%1$s</b>,請點擊此處複製。\n\
\n\
點擊「登入」按鈕後,你應該在打開的登入網頁中完成登入過程。如果網頁沒有打開,你可以自行在瀏覽器中訪問 %2$s\n\
\n\
如果登入 Microsoft 帳戶的令牌洩露,可點擊下方連結解除授權,然後等待令牌過期。\n\
如果登入 Microsoft 帳戶的令牌洩露,可點擊下方「移除應用存取權」,然後等待令牌過期。\n\
\n\
如遇到問題,你可以點擊右上角幫助按鈕進行求助。
account.methods.microsoft.profile=帳戶設定頁
account.methods.microsoft.profile=編輯帳戶配置檔
account.methods.microsoft.purchase=購買 Minecraft
account.methods.forgot_password=忘記密碼
account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL,請下載官方版本進行登入。
@@ -374,12 +375,12 @@ fatal.unsupported_platform.windows_arm64=Hello Minecraft! Launcher 已為 Window
feedback=回報
feedback.channel=回報管道
feedback.discord=Discord
feedback.discord.statement=歡迎加入 Discord 討論區,加入後請遵守討論區規定
feedback.discord=Discord 伺服器
feedback.discord.statement=歡迎加入 Discord 伺服器,加入後請遵守討論區規則
feedback.github=GitHub Issues
feedback.github.statement=提交一個 GitHub Issue
feedback.qq_group=HMCL 使用者群組
feedback.qq_group.statement=歡迎加入 HMCL 使用者群組,加入後請遵守群規
feedback.qq_group=HMCL 使用者 QQ 群組
feedback.qq_group.statement=歡迎加入 HMCL 使用者 QQ 群組,加入後請遵守群組規則
file=檔案
@@ -607,7 +608,7 @@ launcher.background.translucent=半透明
launcher.cache_directory=檔案下載快取目錄
launcher.cache_directory.clean=清理
launcher.cache_directory.choose=選取檔案下載快取目錄
launcher.cache_directory.default=預設 ("%AppData%/.minecraft" 或 "~/.minecraft")
launcher.cache_directory.default=預設 ("%APPDATA%/.minecraft" 或 "~/.minecraft")
launcher.cache_directory.disabled=停用
launcher.cache_directory.invalid=無法建立自訂的快取目錄,還原至預設設定
launcher.contact=聯絡我們
@@ -854,7 +855,7 @@ world.import.failed=無法匯入此世界: %s
world.import.invalid=無法識別的存檔壓縮檔
world.info.title=世界 [%s] - 世界資訊
world.info.basic=基本資訊
world.info.allow_cheats=允許指令
world.info.allow_cheats=允許指令(作弊)
world.info.dimension.the_nether=地獄
world.info.dimension.the_end=末地
world.info.difficulty=難易度
@@ -986,8 +987,8 @@ settings.advanced.renderer.llvmpipe=軟繪製器 (效能較差,相容性最好
settings.advanced.renderer.zink=Vulkan (效能最好,相容性較差)
settings.advanced.server_ip=伺服器位址
settings.advanced.server_ip.prompt=預設,啟動遊戲後直接進入對應伺服器
settings.advanced.use_native_glfw=使用系統 GLFW
settings.advanced.use_native_openal=使用系統 OpenAL
settings.advanced.use_native_glfw=[僅限 Linux/FreeBSD] 使用系統 GLFW
settings.advanced.use_native_openal=[僅限 Linux/FreeBSD] 使用系統 OpenAL
settings.advanced.workaround=除錯選項
settings.advanced.workaround.warning=除錯選項僅提供給專業玩家使用。修改除錯選項可能會導致遊戲無法啟動。除非你知道你在做什麼,否則請不要修改這些選項。
settings.advanced.wrapper_launcher=前置指令
@@ -1072,8 +1073,8 @@ settings.type.special.edit=編輯實例特定遊戲設定
settings.type.special.edit.hint=目前實例「%s」啟用了「實例特定遊戲設定」,本頁面選項不對目前實例生效。點擊連結以修改目前實例設定。
sponsor=贊助
sponsor.bmclapi=中國大陸下載源由 BMCLAPI 提供高速下載服務。
sponsor.hmcl=Hello Minecraft! Launcher 是一個免費、自由、開源的 Minecraft 啟動器,允許玩家方便快捷地安裝、管理、執行遊戲。點選此處查閱更多詳細訊息。
sponsor.bmclapi=中國大陸下載源由 BMCLAPI 提供高速下載服務。點選此處查閱詳細訊息。
sponsor.hmcl=Hello Minecraft! Launcher 是一個免費、自由、開源的 Minecraft 啟動器,允許玩家方便快捷地安裝、管理、執行遊戲。點選此處查閱詳細訊息。
system.architecture=架構
system.operating_system=作業系統
@@ -1084,15 +1085,13 @@ update=啟動器更新
update.accept=更新
update.changelog=更新日誌
update.channel.dev=開發版
update.channel.dev.hint=你正在使用 HMCL 開發版。開發版包含一些未在穩定版中包含的測試性功能,僅用於體驗新功能。\n\
開發版功能未受充分驗證,使用起來可能不穩定!\n\
如果你遇到了使用問題,可以透過設定中 <a href="hmcl://settings/feedback">回報頁面</a> 提供的管道進行回報。\n\
update.channel.dev.hint=你正在使用 HMCL 開發版。開發版包含一些未在穩定版中包含的測試性功能,僅用於體驗新功能。開發版功能未受充分驗證,使用起來可能不穩定!\n\
\n\
<a href="hmcl://hide-announcement">為目前版本隱藏該提示</a>。
如果你遇到了使用問題,可以透過設定中 <a href="hmcl://settings/feedback">回報頁面</a> 提供的管道進行回報。
update.channel.dev.title=開發版提示
update.channel.nightly=預覽版
update.channel.nightly.hint=你正在使用 HMCL 預覽版。預覽版更新較為頻繁,包含一些未在穩定版和開發版中包含的測試性功能,僅用於體驗新功能。\n\
預覽版功能未受充分驗證,使用起來可能不穩定!\n\
update.channel.nightly.hint=你正在使用 HMCL 預覽版。預覽版更新較為頻繁,包含一些未在穩定版和開發版中包含的測試性功能,僅用於體驗新功能。預覽版功能未受充分驗證,使用起來可能不穩定!\n\
\n\
如果你遇到了使用問題,可以透過設定中 <a href="hmcl://settings/feedback">回報頁面</a> 提供的管道進行回報。
update.channel.nightly.title=預覽版提示
update.channel.stable=穩定版
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2023 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2024 huangyuhui <huanghongxun2008@126.com> 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
@@ -17,6 +17,7 @@
#
# Contributors: huangyuhui
about=关于
about.copyright=版权
about.copyright.statement=版权所有 © 2024 huangyuhui
@@ -64,7 +65,7 @@ account.failed.injector_download_failure=无法下载 authlib-injector,可能
account.failed.invalid_credentials=你的用户名或密码错误,或登录次数过多被暂时禁止登录,请稍后再试。
account.failed.invalid_password=无效的密码
account.failed.invalid_token=请尝试登出并重新输入密码登录
account.failed.migration=你的账户需要迁移至微软账户。如果你已经迁移,你需要使用微软账户登录迁移后的账户。
account.failed.migration=你的账户需要迁移至微软账户。如果你已经迁移,你需要使用迁移后的微软账户登录。
account.failed.no_character=该账户没有角色
account.failed.server_disconnected=无法访问登录服务器,账户信息刷新失败。\n\
你可以选择“再次刷新账户”重新尝试。\n\
@@ -98,11 +99,11 @@ account.copy_uuid=复制该账户的 UUID
account.methods=登录方式
account.methods.authlib_injector=外置登录 (authlib-injector)
account.methods.microsoft=微软账户
account.methods.microsoft.birth=如何修改账户出生日期
account.methods.microsoft.birth=如何更改账户出生日期
account.methods.microsoft.close_page=已完成微软账户授权,接下来启动器还需要完成其余登录步骤。你现在可以关闭本页面了。
account.methods.microsoft.deauthorize=解除账户授权
account.methods.microsoft.error.add_family=请点击上方“账户设置页”更改你的账户出生日期,使年龄满 18 岁以上,或将账户加入到家庭中。\n你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.error.add_family_probably=请点击上方“账户设置页”更改你的账户出生日期,使年龄满 18 岁以上,或将账户加入到家庭中。\n你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.error.add_family=请点击上方“编辑账户个人信息”更改你的账户出生日期,使年龄满 18 岁以上,或将账户加入到家庭中。\n你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.error.add_family_probably=请点击上方“编辑账户个人信息”更改你的账户出生日期,使年龄满 18 岁以上,或将账户加入到家庭中。\n你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.error.country_unavailable=你所在的国家或地区不受 Xbox Live 的支持。
account.methods.microsoft.error.missing_xbox_account=请点击上方“创建档案”关联 Xbox 账户。\n你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.error.no_character=请确认你已经购买了 Minecraft: Java 版。\n若已购买,则可能未创建游戏档案,请点击上方“创建档案”以创建游戏档案。\n你可以点击右上角帮助按钮进行求助。
@@ -111,25 +112,25 @@ account.methods.microsoft.error.wrong_verify_method=请在微软账户登录页
account.methods.microsoft.logging_in=登录中……
account.methods.microsoft.makegameidsettings=创建档案 / 编辑档案名称
account.methods.microsoft.hint=你需要按照以下步骤添加账户:\n\
\ 1.点击“登录”按钮;\n\
\ 2.在弹出的网页中输入 HMCL 显示的代码,并点击“下一步”;\n\
\ 3.按照网站的提示登录;\n\
\ 4.当网站提示“是否允许此应用访问你的信息?”的标识时,请点击“是”;\n\
\ 5.在网站提示“大功告成”后,只需等待账户完成添加即可。\n\
若网站提示“出现错误”的标识或账户添加失败时,请重新按照以上步骤重新添加。\n\
<b>若设备网络环境不佳,可能登录网站加载很慢甚至无法加载,此时请使用网络代理并重试。</b>\n\
\ 1. 点击“登录”按钮;\n\
\ 2. 在弹出的网页中输入 HMCL 显示的代码,并点击“允许访问”;\n\
\ 3. 按照网站的提示登录;\n\
\ 4. 当网站提示“是否允许此应用访问你的信息?”时,请点击“接受”;\n\
\ 5. 在网站提示“大功告成”后,等待账户完成添加即可。\n\
若网站提示“出现错误”或账户添加失败时,请按照以上步骤重新添加。\n\
<b>若设备网络环境不佳,可能会导致网页加载缓慢甚至无法加载,请使用网络代理并重试。</b>\n\
如遇到问题,你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.manual=你需要按照以下步骤添加:\n\
\ 1.点击“登录”按钮;\n\
\ 2.在弹出的网页中输入:<b>%1$s</b> (已自动复制,点此再次复制),并点击“下一步”;\n\
\ 3.按照网站的提示登录;\n\
\ 4.当网站提示“是否允许此应用访问你的信息?”的标识时,请点击“是”;\n\
\ 5.在网站提示“大功告成”后,只需等待账户完成添加即可。\n\
\ 1. 点击“登录”按钮;\n\
\ 2. 在弹出的网页中输入 <b>%1$s</b> (已自动复制),并点击“允许访问”;\n\
\ 3. 按照网站的提示登录;\n\
\ 4. 当网站提示“是否允许此应用访问你的信息?”时,请点击“接受”;\n\
\ 5. 在网站提示“大功告成”后,等待账户完成添加即可。\n\
若网站未能显示,请手动在浏览器中打开:%2$s\n\
若网站提示“出现错误”的标识或账户添加失败时,请重新按照以上步骤重新添加。\n\
<b>若设备网络环境不佳,可能登录网站加载很慢甚至无法加载,此时请使用网络代理并重试。</b>\n\
若网站提示“出现错误”或账户添加失败时,请按照以上步骤重新添加。\n\
<b>若设备网络环境不佳,可能会导致网页加载缓慢甚至无法加载,请使用网络代理并重试。</b>\n\
如遇到问题,你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.profile=账户设置页
account.methods.microsoft.profile=编辑账户个人信息
account.methods.microsoft.purchase=购买 Minecraft
account.methods.forgot_password=忘记密码
account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL,请下载官方版本来登录微软账户。
@@ -385,7 +386,7 @@ fatal.unsupported_platform.windows_arm64=Hello Minecraft! Launcher 已为 Window
feedback=反馈
feedback.channel=反馈渠道
feedback.discord=Discord
feedback.discord.statement=欢迎加入 Discord 讨论区,加入后请遵守讨论区规定
feedback.discord.statement=欢迎加入 Discord 服务器,加入后请遵守讨论区规定
feedback.github=GitHub Issue
feedback.github.statement=提交一个 GitHub Issue
feedback.qq_group=HMCL 用户群
@@ -557,7 +558,7 @@ java.reveal=浏览 Java 文件夹
java.uninstall=卸载此 Java
java.uninstall.confirm=你确定要卸载此 Java 吗?此操作无法撤销!
lang=简体中文 (中国大陆)
lang=简体中文
lang.default=跟随系统语言
launch.advice==%s 是否继续启动?
@@ -618,7 +619,7 @@ launcher.background.translucent=半透明
launcher.cache_directory=文件下载缓存文件夹
launcher.cache_directory.clean=清理缓存
launcher.cache_directory.choose=选择文件下载缓存文件夹
launcher.cache_directory.default=默认 ("%AppData%/.minecraft" 或 "~/.minecraft")
launcher.cache_directory.default=默认 ("%APPDATA%/.minecraft" 或 "~/.minecraft")
launcher.cache_directory.disabled=禁用 (总是使用游戏文件夹路径)
launcher.cache_directory.invalid=无法创建自定义的缓存文件夹,恢复默认设置
launcher.contact=联系我们
@@ -866,7 +867,7 @@ world.import.failed=无法导入此世界:%s
world.import.invalid=无法识别该存档压缩包
world.info.title=世界 [%s] - 世界信息
world.info.basic=基本信息
world.info.allow_cheats=允许作弊
world.info.allow_cheats=允许命令(作弊)
world.info.dimension.the_nether=下界
world.info.dimension.the_end=末地
world.info.difficulty=难度
@@ -943,17 +944,17 @@ settings.advanced.modify=编辑高级设置
settings.advanced.title=高级设置 - %s
settings.advanced.custom_commands=自定义命令
settings.advanced.custom_commands.hint=自定义命令被调用时将包含如下的环境变量:\n\
\ · $INST_NAME:版本名称;\n\
\ · $INST_ID:版本名称;\n\
\ · $INST_DIR:当前版本运行路径;\n\
\ · $INST_MC_DIR:当前游戏文件夹路径;\n\
\ · $INST_JAVA:游戏运行使用的 Java 路径;\n\
\ · $INST_FORGE:若安装了 Forge,将会存在本环境变量;\n\
\ · $INST_NEOFORGE:若安装了 NeoForge,将会存在本环境变量;\n\
\ · $INST_LITELOADER:若安装了 LiteLoader,将会存在本环境变量;\n\
\ · $INST_OPTIFINE:若安装了 OptiFine,将会存在本环境变量;\n\
\ · $INST_FABRIC:若安装了 Fabric,将会存在本环境变量;\n\
\ · $INST_QUILT:若安装了 Quilt,将会存在本环境变量。
\ · $INST_NAME: 版本名称;\n\
\ · $INST_ID: 版本名称;\n\
\ · $INST_DIR: 当前版本运行路径;\n\
\ · $INST_MC_DIR: 当前游戏文件夹路径;\n\
\ · $INST_JAVA: 游戏运行使用的 Java 路径;\n\
\ · $INST_FORGE: 若安装了 Forge,将会存在本环境变量;\n\
\ · $INST_NEOFORGE: 若安装了 NeoForge,将会存在本环境变量;\n\
\ · $INST_LITELOADER: 若安装了 LiteLoader,将会存在本环境变量;\n\
\ · $INST_OPTIFINE: 若安装了 OptiFine,将会存在本环境变量;\n\
\ · $INST_FABRIC: 若安装了 Fabric,将会存在本环境变量;\n\
\ · $INST_QUILT: 若安装了 Quilt,将会存在本环境变量。
settings.advanced.dont_check_game_completeness=不检查游戏完整性
settings.advanced.dont_check_jvm_validity=不检查 JVM 与游戏的兼容性
settings.advanced.dont_patch_natives=不尝试自动替换本地库
@@ -997,8 +998,8 @@ settings.advanced.renderer.llvmpipe=软渲染器 (性能较差,兼容性最好
settings.advanced.renderer.zink=Vulkan (性能最好,兼容性较差)
settings.advanced.server_ip=服务器地址
settings.advanced.server_ip.prompt=默认,启动游戏后可以直接进入对应服务器
settings.advanced.use_native_glfw=使用系统 GLFW
settings.advanced.use_native_openal=使用系统 OpenAL
settings.advanced.use_native_glfw=[仅 Linux/FreeBSD] 使用系统 GLFW
settings.advanced.use_native_openal=[仅 Linux/FreeBSD] 使用系统 OpenAL
settings.advanced.workaround=调试选项
settings.advanced.workaround.warning=调试选项仅提供给专业玩家使用。调试选项可能会导致游戏无法启动。除非你知道你在做什么,否则请不要修改这些选项!
settings.advanced.wrapper_launcher=包装命令
@@ -1083,8 +1084,8 @@ settings.type.special.edit=编辑版本特定游戏设置
settings.type.special.edit.hint=当前游戏版本“%s”启用了“版本特定游戏设置”,因此本页面选项不对该版本生效。点击链接前往该版本的“游戏设置”页。
sponsor=赞助
sponsor.bmclapi=国内下载源由 BMCLAPI 提供高速下载服务。BMCLAPI 为公益服务,赞助 BMCLAPI 可以帮助作者更好的提供稳定高速的下载服务。[点击此处查阅详细信息]
sponsor.hmcl=Hello Minecraft! Launcher 是一个免费、自由、开放源代码的 Minecraft 启动器。[点击此处查阅更多详细信息]
sponsor.bmclapi=国内下载源由 BMCLAPI 提供高速下载服务。BMCLAPI 为公益服务,赞助 BMCLAPI 可以帮助作者更好地提供稳定高速的下载服务。[点击此处查阅详细信息]
sponsor.hmcl=Hello Minecraft! Launcher 是一个免费、自由、开放源代码的 Minecraft 启动器。[点击此处查阅详细信息]
system.architecture=架构
system.operating_system=操作系统
@@ -1095,15 +1096,13 @@ update=启动器更新
update.accept=更新
update.changelog=更新日志
update.channel.dev=开发版
update.channel.dev.hint=你正在使用 HMCL 开发版。开发版包含一些未在稳定版中包含的测试性功能,仅用于体验新功能。\n\
开发版功能未受充分验证,使用起来可能不稳定!<a href="https://hmcl.huangyuhui.net/download">下载稳定版</a>\n\
如果你使用时遇到了问题,可以通过设置中<a href="hmcl://settings/feedback">反馈页面</a>提供的渠道进行反馈。欢迎关注 B 站账号 <a href="https://space.bilibili.com/1445341">@huanghongxun</a> 以关注 HMCL 的开发进展。\n\
update.channel.dev.hint=你正在使用 HMCL 开发版。开发版包含一些未在稳定版中包含的测试性功能,仅用于体验新功能。开发版功能未受充分验证,使用起来可能不稳定!<a href="https://hmcl.huangyuhui.net/download">下载稳定版</a>\n\
\n\
<a href="hmcl://hide-announcement">为当前版本隐藏该提示</a>。
如果你使用时遇到了问题,可以通过设置中<a href="hmcl://settings/feedback">反馈页面</a>提供的渠道进行反馈。欢迎关注 B 站账号 <a href="https://space.bilibili.com/1445341">@huanghongxun</a> 以关注 HMCL 的开发进展。
update.channel.dev.title=开发版提示
update.channel.nightly=预览版
update.channel.nightly.hint=你正在使用 HMCL 预览版。预览版更新较为频繁,包含一些未在稳定版和开发版中包含的测试性功能,仅用于体验新功能。\n\
预览版功能未受充分验证,使用起来可能不稳定!<a href="https://hmcl.huangyuhui.net/download">下载稳定版</a>\n\
update.channel.nightly.hint=你正在使用 HMCL 预览版。预览版更新较为频繁,包含一些未在稳定版和开发版中包含的测试性功能,仅用于体验新功能。预览版功能未受充分验证,使用起来可能不稳定!<a href="https://hmcl.huangyuhui.net/download">下载稳定版</a>\n\
\n\
如果你使用时遇到了问题,可以通过设置中<a href="hmcl://settings/feedback">反馈页面</a>提供的渠道进行反馈。欢迎关注 B 站账号 <a href="https://space.bilibili.com/1445341">@huanghongxun</a> 以关注 HMCL 的开发进展。
update.channel.nightly.title=预览版提示
update.channel.stable=稳定版
@@ -1,4 +1,4 @@
package moe.mickey.minecraft.skin.fx;
package org.jackhuang.hmcl.ui.skin;
import javafx.application.Platform;
import javafx.scene.Scene;
@@ -8,7 +8,7 @@ import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.input.TransferMode;
import javafx.stage.Stage;
import moe.mickey.minecraft.skin.fx.test.Test;
import org.jackhuang.hmcl.ui.skin.test.Test;
import java.io.File;
import java.io.FileInputStream;
@@ -1,13 +1,13 @@
package moe.mickey.minecraft.skin.fx.test;
package org.jackhuang.hmcl.ui.skin.test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import moe.mickey.minecraft.skin.fx.FunctionHelper;
import moe.mickey.minecraft.skin.fx.SkinCanvas;
import moe.mickey.minecraft.skin.fx.SkinCanvasSupport;
import moe.mickey.minecraft.skin.fx.animation.SkinAniRunning;
import moe.mickey.minecraft.skin.fx.animation.SkinAniWavingArms;
import org.jackhuang.hmcl.ui.skin.FunctionHelper;
import org.jackhuang.hmcl.ui.skin.SkinCanvas;
import org.jackhuang.hmcl.ui.skin.SkinCanvasSupport;
import org.jackhuang.hmcl.ui.skin.animation.SkinAniRunning;
import org.jackhuang.hmcl.ui.skin.animation.SkinAniWavingArms;
import org.jackhuang.hmcl.game.TexturesLoader;
import java.util.function.Consumer;
+1 -1
View File
@@ -6,7 +6,7 @@ dependencies {
api("org.glavo:simple-png-javafx:0.3.0")
api("com.google.code.gson:gson:2.11.0")
api("com.moandjiezana.toml:toml4j:0.7.2")
api("org.tukaani:xz:1.9")
api("org.tukaani:xz:1.10")
api("org.hildan.fxgson:fx-gson:5.0.0")
api("org.jenkins-ci:constant-pool-scanner:1.2")
api("com.github.steveice10:opennbt:1.5")
+2 -1
View File
@@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.25)
project(HMCLauncher)
if(MSVC)
add_compile_options(/utf-8 /D_UNICODE /W4)
add_definitions(-DUNICODE -D_UNICODE)
add_compile_options(/utf-8 /W4)
add_link_options(/ENTRY:wWinMainCRTStartup)
else()
add_compile_options(-municode -Wall -Wextra -Wpedantic)
+2 -2
View File
@@ -82,8 +82,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,4,0,0
PRODUCTVERSION 3,4,0,0
FILEVERSION 3,5,0,0
PRODUCTVERSION 3,5,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
-225
View File
@@ -1,225 +0,0 @@
param(
[string]$JavaDir,
[string]$Arch
)
$chinese = [System.Globalization.CultureInfo]::CurrentCulture.Name -eq 'zh-CN'
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.Application]::EnableVisualStyles()
# Choose Source Dialog
$dialog = New-Object System.Windows.Forms.Form
$dialog.AutoSize = $true
$dialog.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
if ($chinese) {
$dialog.Text = '未能在这台电脑上找到 Java'
} else {
$dialog.Text = 'Java not found'
}
$dialogLayout = New-Object System.Windows.Forms.FlowLayoutPanel
$dialogLayout.AutoSize = $true
$dialogLayout.FlowDirection = [System.Windows.Forms.FlowDirection]::TopDown
$dialogLayout.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$messageLabel = New-Object System.Windows.Forms.Label
$messageLabel.AutoSize = $true
$messageLabel.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom
if ($chinese) {
$messageLabel.Text = "HMCL 需要 Java 运行时环境才能正常运行,是否自动下载安装 Java?"
} else {
$messageLabel.Text = "Running HMCL requires a Java runtime environment. `nDo you want to download and install Java automatically?"
}
$useMirrorCheckBox = New-Object System.Windows.Forms.CheckBox
$useMirrorCheckBox.AutoSize = $true
$useMirrorCheckBox.Anchor = [System.Windows.Forms.AnchorStyles]::Right
$useMirrorCheckBox.Checked = $false
if ($chinese) {
$useMirrorCheckBox.Text = '使用备用下载源(如果无法正常下载,请打开它再试一次)'
} else {
$useMirrorCheckBox.Text = 'Use the alternate download source'
}
$selectButtonPanel = New-Object System.Windows.Forms.FlowLayoutPanel
$selectButtonPanel.AutoSize = $true
$selectButtonPanel.Anchor = [System.Windows.Forms.AnchorStyles]::Right
$selectButtonPanel.FlowDirection = [System.Windows.Forms.FlowDirection]::LeftToRight
$selectButtonPanel.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$yesButton = New-Object System.Windows.Forms.Button
$noButton = New-Object System.Windows.Forms.Button
$yesButton.DialogResult = [System.Windows.Forms.DialogResult]::Yes
$noButton.DialogResult = [System.Windows.Forms.DialogResult]::No
if ($chinese) {
$yesButton.Text = '是'
$noButton.Text = '否'
} else {
$yesButton.Text = 'Yes'
$noButton.Text = 'No'
}
$selectButtonPanel.Controls.Add($yesButton)
$selectButtonPanel.Controls.Add($noButton)
$dialogLayout.Controls.Add($messageLabel)
$dialogLayout.Controls.Add($useMirrorCheckBox)
$dialogLayout.Controls.Add($selectButtonPanel)
$dialog.Controls.Add($dialogLayout)
$result = $dialog.ShowDialog()
if ($result -ne [System.Windows.Forms.DialogResult]::Yes) {
exit 0
}
if ($useMirrorCheckBox.Checked) {
switch ($Arch) {
'x86-64' {
$script:url = 'https://download.bell-sw.com/java/17.0.2+9/bellsoft-jre17.0.2+9-windows-amd64-full.zip'
}
'x86' {
$script:url = 'https://download.bell-sw.com/java/17.0.2+9/bellsoft-jre17.0.2+9-windows-i586-full.zip'
}
default { exit 1 }
}
} else {
switch ($Arch) {
'x86-64' {
$script:url = 'https://cdn.azul.com/zulu/bin/zulu17.32.13-ca-fx-jre17.0.2-win_x64.zip'
}
'x86' {
$script:url = 'https://cdn.azul.com/zulu/bin/zulu17.32.13-ca-fx-jre17.0.2-win_i686.zip'
}
default { exit 1 }
}
}
$securityProtocol = [System.Net.ServicePointManager]::SecurityProtocol.value__
if (($securityProtocol -ne 0) -and (($securityProtocol -band 0x00000C00) -eq 0)) { # Try using HTTP when the platform does not support TLS 1.2
$script:url = $script:url -replace '^https:', 'http:'
}
# Download Winodw
do {
$tempFileName = "hmcl-java-$(Get-Random).zip"
$script:tempFile = Join-Path ([System.IO.Path]::GetTempPath()) $tempFileName
} while (Test-Path $script:tempFile)
$form = New-Object System.Windows.Forms.Form
$form.AutoSize = $true
$form.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
if ($chinese) {
$form.Text = '正在下载 Java 中'
} else {
$form.Text = 'Downloading Java'
}
$tip = New-Object System.Windows.Forms.Label
$tip.AutoSize = $true
if ($chinese) {
$tip.Text = '正在下载 Java。这需要一段时间,请耐心等待。'
} else {
$tip.Text = 'Downloading Java. Please wait patiently for the download to complete.'
}
$layout = New-Object System.Windows.Forms.FlowLayoutPanel
$layout.AutoSize = $true
$layout.FlowDirection = [System.Windows.Forms.FlowDirection]::TopDown
$layout.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Maximum = 100
$label = New-Object System.Windows.Forms.Label
$label.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom
if ($chinese) {
$label.Text = '准备下载'
} else {
$label.Text = 'In preparation'
}
$box = New-Object System.Windows.Forms.FlowLayoutPanel
$box.AutoSize = $true
$box.FlowDirection = [System.Windows.Forms.FlowDirection]::LeftToRight
$box.AutoSizeMode = [System.Windows.Forms.AutoSizeMode]::GrowAndShrink
$box.Controls.Add($progressBar)
$box.Controls.Add($label)
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$cancelButton.Anchor = [System.Windows.Forms.AnchorStyles]::Right
if ($chinese) {
$cancelButton.Text = '取消'
} else {
$cancelButton.Text = 'Cancel'
}
$layout.Controls.Add($tip)
$layout.Controls.Add($box)
$box.Controls.Add($cancelButton)
$form.Controls.Add($layout)
[System.Net.DownloadProgressChangedEventHandler]$progressChangedEventHandler = {
param($sender, [System.Net.DownloadProgressChangedEventArgs]$ChangedEventArgs)
$bytesReceived = $ChangedEventArgs.BytesReceived
$totalBytes = $ChangedEventArgs.TotalBytesToReceive
$percentage = ([double]$bytesReceived)/([double]$totalBytes) * 100
$progressBar.Value = [int][System.Math]::Truncate($percentage)
$label.Text = [string]::Format("{0:0.00}%", $percentage)
}
[System.ComponentModel.AsyncCompletedEventHandler]$downloadFileCompletedEventHandler = {
param($sender, [System.ComponentModel.AsyncCompletedEventArgs]$CompletedEventArgs)
if (!$form.IsDisposed) {
$label.Refresh()
if ($CompletedEventArgs.Cancelled) {
$form.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
} elseif ($CompletedEventArgs.Error -ne $null) {
if ($chinese) {
[System.Windows.Forms.MessageBox]::Show($CompletedEventArgs.Error.Message, '下载失败', [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Exclamation)
} else {
[System.Windows.Forms.MessageBox]::Show($CompletedEventArgs.Error.Message, 'Download failed', [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Exclamation)
}
$form.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
} else {
$form.DialogResult = [System.Windows.Forms.DialogResult]::OK
}
}
}
$client = New-Object System.Net.WebClient
$client.Headers.Add('User-Agent', 'Wget/1.20.3 (linux-gnu)')
$client.add_DownloadProgressChanged($progressChangedEventHandler)
$client.add_DownloadFileCompleted($downloadFileCompletedEventHandler)
$client.DownloadFileAsync($script:url, $script:tempFile)
$result = $form.ShowDialog()
$client.CancelAsync()
$form.Dispose()
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
$null = New-Item -Type Directory -Force $JavaDir
$app = New-Object -ComObject Shell.Application
$items = $app.NameSpace($script:tempFile).items()
foreach ($item in $items) {
$app.NameSpace($JavaDir).copyHere($item)
}
}
if ([System.IO.File]::Exists($script:tempFile)) {
try {
[System.IO.File]::Delete($script:tempFile)
} catch {
Write-Error $_
}
}
+2 -4
View File
@@ -6,9 +6,7 @@
#define ERROR_PROMPT L"The Java runtime environment is required to run HMCL and Minecraft,\n"\
L"Click 'OK' to start downloading java.\n"\
L"Please restart HMCL after installing Java.\n"\
L"Click 'Help' go for help."
L"Please restart HMCL after installing Java."
#define ERROR_PROMPT_ZH L"运行 HMCL 以及 Minecraft 需要 Java 运行时环境,点击“确定”开始下载。\n"\
L"请在安装 Java 完成后重新启动 HMCL。\n"\
L"点击“帮助”寻求帮助。"
L"请在安装 Java 完成后重新启动 HMCL。"
+5 -6
View File
@@ -75,12 +75,11 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
bool useChinese = GetUserDefaultUILanguage() == 2052; // zh-CN
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
// TODO: check whether the bundled JRE is valid.
MyArchitecture architecture = MyGetArchitecture();
// First try the Java packaged together.
bool isX64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64);
bool isARM64 = (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64);
bool isX64 = architecture == MyArchitecture::X86_64;
bool isARM64 = architecture == MyArchitecture::ARM64;
if (isARM64) {
RawLaunchJVM(L"jre-arm64\\bin\\javaw.exe", workdir, exeName, jvmOptions);
@@ -143,7 +142,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (isARM64) {
downloadLink = L"https://docs.hmcl.net/downloads/windows/arm64.html";
} if (isX64) {
} else if (isX64) {
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86_64.html";
} else {
downloadLink = L"https://docs.hmcl.net/downloads/windows/x86.html";
+35
View File
@@ -1,6 +1,41 @@
#include "stdafx.h"
#include "os.h"
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS2) (HANDLE, PUSHORT, PUSHORT);
MyArchitecture MyGetArchitecture() {
LPFN_ISWOW64PROCESS2 fnIsWow64Process2 = (LPFN_ISWOW64PROCESS2)GetProcAddress(
GetModuleHandle(L"Kernel32.dll"), "IsWow64Process2");
if (NULL != fnIsWow64Process2) {
USHORT uProcessMachine = 0;
USHORT uNativeMachine = 0;
if (fnIsWow64Process2(GetCurrentProcess(), &uProcessMachine, &uNativeMachine)) {
if (uNativeMachine == 0xAA64) {
return MyArchitecture::ARM64;
}
if (uNativeMachine == 0x8664) {
return MyArchitecture::X86_64;
}
return MyArchitecture::X86;
}
}
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
if (systemInfo.wProcessorArchitecture == 12) { // PROCESSOR_ARCHITECTURE_ARM64
return MyArchitecture::ARM64;
}
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
return MyArchitecture::X86_64;
}
return MyArchitecture::X86;
}
LSTATUS MyRegQueryValue(HKEY hKey, LPCWSTR subKey, DWORD dwType,
std::wstring &out) {
DWORD dwSize = 0;
+7 -3
View File
@@ -8,9 +8,13 @@
const int MAX_KEY_LENGTH = 255;
const int MAX_VALUE_NAME = 16383;
#ifndef PROCESSOR_ARCHITECTURE_ARM64
#define PROCESSOR_ARCHITECTURE_ARM64 12
#endif
enum MyArchitecture {
X86,
X86_64,
ARM64
};
MyArchitecture MyGetArchitecture();
// Query registry value of class root hKey, key path subKey, stores result in
// parameter out.
+5 -5
View File
@@ -17,20 +17,20 @@
Legend:
* ✅: Official supported platform.
* ✅: Officially supported platform.
Fully supported by Mojang official. Problems encountered in the game should be directly reported to the Mojang.
Fully supported by Mojang officials. Problems encountered in the game should be directly reported to the Mojang.
* 👌: Supported platforms.
Support is provided by HMCL, tested to work, but may have more issues than a fully supported platform.
Support is provided by HMCL, tested to work, but may have more problems than a fully supported platform.
Support for versions below Minecraft 1.6 is not guaranteed.
If you encounter a problem that does not exist on fully supported platforms, you can report it to HMCL.
* ❔: Low level supported platforms.
* ❔: Low-level supported platforms.
HMCL can run on this platform and has some basic support. However, launching the game directly is not yet available.
If you want to start the game, you will need to get the native libraries needed by Minecraft in other way and specify the native path in the instance settings.
If you want to start the game, you will need to get the native libraries needed by Minecraft in another way and specify the native path in the instance settings.
* `/`: Not applicable.
+7 -7
View File
@@ -10,7 +10,7 @@
## Introduction
HMCL is an open-source, cross-platform Minecraft launcher that supports Mod Management, Game Customizing, ModLoader Installing (Forge, NeoForge, Fabric, Quilt, LiteLoader and OptiFine), Modpack Creating, UI Customization, and more.
HMCL is an open-source, cross-platform Minecraft launcher that supports Mod Management, Game Customizing, ModLoader Installing (Forge, NeoForge, Fabric, Quilt, LiteLoader, and OptiFine), Modpack Creating, UI Customization, and more.
HMCL has amazing cross-platform capabilities. Not only does it run on different operating systems like Windows, Linux, and macOS, but it also supports various CPU architectures such as x86, ARM, MIPS, and LoongArch. You can easily enjoy Minecraft across different platforms through HMCL.
@@ -46,7 +46,7 @@ If you want to submit a pull request, here are some requirements:
### Compilation
Simply execute the following command in project root directory:
Simply execute the following command in the project root directory:
```bash
./gradlew clean build
@@ -59,13 +59,13 @@ Make sure you have at least JavaFX 8 installed. Liberica Full JDK 8 or later is
| Parameter | Description |
| -------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `-Dhmcl.home=<path>` | Override HMCL directory |
| `-Dhmcl.self_integrity_check.disable=true` | Bypass the self integrity check when checking for update |
| `-Dhmcl.bmclapi.override=<url>` | Override API Root of BMCLAPI download provider, defaults to `https://bmclapi2.bangbang93.com` |
| `-Dhmcl.self_integrity_check.disable=true` | Bypass the self integrity check when checking for updates |
| `-Dhmcl.bmclapi.override=<url>` | Override API Root of BMCLAPI download provider. Defaults to `https://bmclapi2.bangbang93.com` |
| `-Dhmcl.font.override=<font family>` | Override font family |
| `-Dhmcl.version.override=<version>` | Override the version number |
| `-Dhmcl.update_source.override=<url>` | Override the update source for HMCL itself |
| `-Dhmcl.authlibinjector.location=<path>` | Use specified authlib-injector (instead of downloading one) |
| `-Dhmcl.openjfx.repo=<maven repository url>` | Add custom Maven repository for download OpenJFX |
| `-Dhmcl.authlibinjector.location=<path>` | Use the specified authlib-injector (instead of downloading one) |
| `-Dhmcl.openjfx.repo=<maven repository url>` | Add custom Maven repository for downloading OpenJFX |
| `-Dhmcl.native.encoding=<encoding>` | Override the native encoding |
| `-Dhmcl.microsoft.auth.id=<App ID>` | Override Microsoft OAuth App ID |
| `-Dhmcl.microsoft.auth.secret=<App Secret>` | Override Microsoft OAuth App secret |
| `-Dhmcl.microsoft.auth.secret=<App Secret>` | Override Microsoft OAuth App Secret |
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=120000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+5 -2
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Vendored
+12 -10
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail