Compare commits

...
Author SHA1 Message Date
8d876fbff5 [release/3.6] 为不同类型的 Dialog 指定相应的默认标题 (#5671)
https://github.com/HMCL-dev/HMCL/pull/5079
https://github.com/HMCL-dev/HMCL/pull/5152
https://github.com/HMCL-dev/HMCL/pull/5633

Co-authored-by: neveler <55753029+neveler@users.noreply.github.com>
Co-authored-by: Glavo <zjx001202@gmail.com>
Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
2026-03-23 22:07:21 +08:00
辞庐andGlavo 4c1f15c98c [release/3.6] 修复 CurseForge 源无法搜索到内容的问题 (#5733)
Co-authored-by: Glavo <zjx001202@gmail.com>
2026-03-08 22:13:54 +08:00
3gf8jv4dv e8b9d98c99 [release/3.6] chore: update copyright year and attribution (#5670)
https://github.com/HMCL-dev/HMCL/pull/5622
2026-03-07 21:50:58 +08:00
3gf8jv4dv 61b7eb34f6 [release/3.6] fix(l10n): replace mcedit with minecraft wiki's tutorial page (#5672)
https://github.com/HMCL-dev/HMCL/pull/5524
2026-03-07 21:39:05 +08:00
3gf8jv4dv a2df345b3c [release/3.6] style(l10n): simplify update button text in mod management header (#5673)
https://github.com/HMCL-dev/HMCL/pull/4712
2026-03-07 21:37:56 +08:00
3gf8jv4dv 70030a9558 [release/3.6] fix(i18n): update i18n for open dir button on instance mods tab (#5674)
https://github.com/HMCL-dev/HMCL/pull/4734
2026-03-03 21:45:00 +08:00
Glavoand3gf8jv4dv f03a4ff807 [release/3.6] 添加“提前预览 HMCL 版本”选项 (#4668)
https://github.com/HMCL-dev/HMCL/pull/4223
https://github.com/HMCL-dev/HMCL/pull/4598
https://github.com/HMCL-dev/HMCL/pull/4599

---------

Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
2025-10-13 15:38:29 +08:00
Glavo de9a105f2f [release/3.6] Update versions.txt to 1.21.10 (#4667)
https://github.com/HMCL-dev/HMCL/pull/4626
2025-10-13 15:27:48 +08:00
Glavo b5d3653c9a [release/3.6] 移除 Pack200 支持 (#4666)
https://github.com/HMCL-dev/HMCL/pull/4267
2025-10-13 15:23:53 +08:00
Glavo 554503fff0 [release/3.6] 在 CacheRepository.ETagItem 中添加 expires 字段 (#4662) 2025-10-13 15:12:51 +08:00
Glavo 785f334241 [release/3.6] 更新 Jenkins CI 服务器的发布模型 (#4582)
https://github.com/HMCL-dev/HMCL/pull/4559
2025-10-02 20:38:58 +08:00
GlavoandShulkerSakura 0b87959716 [release/3.6] Added 16 characters length detection of username (#4580)
https://github.com/HMCL-dev/HMCL/pull/4088

Co-authored-by: ShulkerSakura <50770360+ShulkerSakura@users.noreply.github.com>
2025-10-01 20:44:11 +08:00
Glavoand8Mi_Yile ae18ca7567 [release/3.6] 更新 unlisted-versions-of-minecraft 镜像源地址 (#4579)
https://github.com/HMCL-dev/HMCL/pull/4120

Co-authored-by: 8Mi_Yile <admin@8mi.tech>
2025-10-01 20:34:56 +08:00
Glavoand3gf8jv4dv 7ebdc783c6 [release/3.6] chore: update versions.txt to 1.21.9 (#4578)
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
2025-10-01 20:22:18 +08:00
Glavo 39abdf1ecf [release/3.6] 修复启用代理身份认证且未设置密码时启动器崩溃的问题 (#4536)
https://github.com/HMCL-dev/HMCL/pull/4465
2025-09-23 11:11:19 +08:00
Glavo 8df6563d56 [release/3.6] 修复滚动切换游戏实例/账户功能 (#4535)
https://github.com/HMCL-dev/HMCL/pull/4466
2025-09-22 22:39:38 +08:00
Glavo f62c12fd3c [release/3.6] 优化 Java 自动选择规则 (#4534)
https://github.com/HMCL-dev/HMCL/pull/4515
2025-09-22 22:32:11 +08:00
Glavo 1205212e52 [release/3.6] 修复使用 JavaFX 25 时游戏下载界面布局错误的问题 (#4533)
https://github.com/HMCL-dev/HMCL/pull/4508
2025-09-22 22:25:32 +08:00
Glavo 0d9a275fb3 [release/3.6] 检测到配置文件由高版本启动器创建时禁止保存配置文件 (#4449)
https://github.com/HMCL-dev/HMCL/pull/4414
2025-09-11 01:19:56 +08:00
Glavoand3gf8jv4dv ab72ac3d10 [release/3.6] chore(l10n): change translation from 版本 to 实例 in zh-cn for term INSTANCE (#4448)
https://github.com/HMCL-dev/HMCL/pull/4376

---------

Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
2025-09-11 00:24:53 +08:00
Glavoand辞庐 9d5f8a9f0e [release/3.6] 修复 LWJGL 路径显示错误的问题 (#4447)
https://github.com/HMCL-dev/HMCL/pull/4192

Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
2025-09-11 00:15:13 +08:00
GlavoandWulian233 fe2e96345b [release/3.6] 修复世界管理页面不支持显示极限模式的问题 (#4446)
https://github.com/HMCL-dev/HMCL/pull/4321

Co-authored-by: Wulian233 <1055917385@qq.com>
2025-09-11 00:05:23 +08:00
Glavoand辞庐 881fa2858f [release/3.6] 修复整合包格式不匹配提示未被正确格式化的问题 (#4445)
https://github.com/HMCL-dev/HMCL/pull/4176

Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
2025-09-11 00:01:11 +08:00
Glavo a0b95866be [release/3.6] Update microsoft_auth.html (#4444)
https://github.com/HMCL-dev/HMCL/pull/4388
2025-09-10 23:53:35 +08:00
Glavo 93bbef385d [release/3.6] 修复 RemoteMod::getIntegrityCheck 未选择正确的算法的问题 (#4443)
https://github.com/HMCL-dev/HMCL/pull/4238
2025-09-10 23:44:09 +08:00
Glavoand神奇的赵二 9dcc2727aa [release/3.6] 新增内存显示条禁用样式 (#4442)
https://github.com/HMCL-dev/HMCL/pull/4185

Co-authored-by: 神奇的赵二 (OrzMiku) <miku@ecy.pink>
2025-09-10 23:39:12 +08:00
Glavoand辞庐 865c8588d8 [release/3.6] 修复“下载线程数”的指示器被提示覆盖的问题 (#4441)
https://github.com/HMCL-dev/HMCL/pull/4153

Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
2025-09-10 23:34:52 +08:00
3gf8jv4dvand辞庐 419612bd3e [release/3.6] backport language file changes to the 3.6 branch (#4319)
https://github.com/HMCL-dev/HMCL/pull/3690
https://github.com/HMCL-dev/HMCL/pull/4149
https://github.com/HMCL-dev/HMCL/pull/4188
https://github.com/HMCL-dev/HMCL/pull/4189
https://github.com/HMCL-dev/HMCL/pull/4199
https://github.com/HMCL-dev/HMCL/pull/4200
https://github.com/HMCL-dev/HMCL/pull/4303

---------

Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
2025-09-10 23:34:13 +08:00
Glavo d16eded1ad [release/3.6] 弃用 Java 11 支持 (#4422) 2025-09-10 23:24:51 +08:00
Glavo c3a47655f0 [release/3.6] 更新模组和整合包数据 (#4440)
https://github.com/HMCL-dev/HMCL/pull/4439
2025-09-10 23:21:30 +08:00
Glavo 34842a5f26 [release/3.6] 修复无法加载 WebP 图标的问题 (#4436)
https://github.com/HMCL-dev/HMCL/pull/4171
2025-09-10 23:20:27 +08:00
Glavo 6dd7d53c20 [release/3.6] 修复 backgroundType 为 null 时启动器崩溃的问题 (#4438)
https://github.com/HMCL-dev/HMCL/pull/4437
2025-09-10 22:58:18 +08:00
Glavo 1654c652e0 [release/3.6] 在 ./.hmcl/java 中搜索 Java (#4434)
https://github.com/HMCL-dev/HMCL/pull/4179
2025-09-10 21:37:45 +08:00
Glavoand辞庐 881f5e7874 [release/3.6] 模组下载列表翻页后自动回到顶部 (#4433)
https://github.com/HMCL-dev/HMCL/pull/4170

Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
2025-09-10 21:28:03 +08:00
Glavo 73f0eb472a [release/3.6] 修复首次打开子页面时切换动画丢失的问题 (#4431)
https://github.com/HMCL-dev/HMCL/pull/4365
2025-09-10 21:17:00 +08:00
Glavo e13b8385e0 [release/3.6] 在 Windows 7/8/8.1 上使用 llvmpipe-loader 加载 mesa (#4430)
https://github.com/HMCL-dev/HMCL/pull/4224
2025-09-10 21:01:36 +08:00
Glavo a6e4651307 [release/3.6] 修复非 Windows 平台上游戏进程的 user.home 可能被设置为 null 的问题 (#4427)
https://github.com/HMCL-dev/HMCL/pull/4241
2025-09-10 20:55:33 +08:00
Glavo 554e573d7f [release/3.6] 支持通过环境变量强制使用 GPU 渲染和控制动画帧率 (#4426)
https://github.com/HMCL-dev/HMCL/pull/4164
2025-09-10 20:46:51 +08:00
Glavo 3096f933af [release/3.6] 修复导入异常格式的数据包时启动器崩溃的问题 (#4425)
https://github.com/HMCL-dev/HMCL/pull/4152
2025-09-10 20:41:29 +08:00
GlavoandWulian233 ff3b486f58 [release/3.6] 修复游戏版本列表错误地过滤掉部分版本的问题 (#4424)
https://github.com/HMCL-dev/HMCL/pull/4066
https://github.com/HMCL-dev/HMCL/pull/4244

---------

Co-authored-by: Wulian233 <1055917385@qq.com>
2025-09-10 20:36:01 +08:00
GlavoandRoj234 708e0326a7 [release/3.6] 修复多次启动游戏时内存泄露的问题 (#4423)
https://github.com/HMCL-dev/HMCL/pull/4121

Co-authored-by: Roj234 <82699138+roj234@users.noreply.github.com>
2025-09-10 20:27:12 +08:00
GlavoandWulian233 f7a5c7a310 [release/3.6] 修复 1.21.5 以上的地图跳转种子地图错误 (#4317)
https://github.com/HMCL-dev/HMCL/pull/4274

Co-authored-by: Wulian233 <1055917385@qq.com>
2025-08-22 20:48:56 +08:00
Glavo 633e8f8fe2 [release/3.6] Update amdgpu.ids (#4316) 2025-08-22 20:44:36 +08:00
Glavoand辞庐 440ea1b21d [release/3.6] fix: 无法从 BMCLAPI 下载 NeoForge 所有所需文件 (#4313)
https://github.com/HMCL-dev/HMCL/pull/4174

Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
2025-08-22 20:36:18 +08:00
72 changed files with 2978 additions and 857 deletions

No files matched your search

+27 -19
View File
@@ -1,4 +1,7 @@
import org.jackhuang.hmcl.gradle.ci.GitHubActionUtils
import org.jackhuang.hmcl.gradle.ci.JenkinsUtils
import org.jackhuang.hmcl.gradle.mod.ParseModDataTask
import org.jackhuang.hmcl.gradle.utils.PropertiesUtils
import java.net.URI
import java.nio.file.FileSystems
import java.nio.file.Files
@@ -12,30 +15,36 @@ plugins {
alias(libs.plugins.shadow)
}
val isOfficial = System.getenv("HMCL_SIGNATURE_KEY") != null
|| (System.getenv("GITHUB_REPOSITORY_OWNER") == "HMCL-dev" && System.getenv("GITHUB_BASE_REF")
.isNullOrEmpty())
val projectConfig = PropertiesUtils.load(rootProject.file("config/project.properties").toPath())
val isOfficial = JenkinsUtils.IS_ON_CI || GitHubActionUtils.IS_ON_OFFICIAL_REPO
val buildNumber = System.getenv("BUILD_NUMBER")?.toInt().let { number ->
val offset = System.getenv("BUILD_NUMBER_OFFSET")?.toInt() ?: 0
if (number != null) {
(number - offset).toString()
} else {
val shortCommit = System.getenv("GITHUB_SHA")?.lowercase()?.substring(0, 7)
val prefix = if (isOfficial) "dev" else "unofficial"
if (!shortCommit.isNullOrEmpty()) "$prefix-$shortCommit" else "SNAPSHOT"
}
}
val versionRoot = System.getenv("VERSION_ROOT") ?: "3.6"
val versionType = System.getenv("VERSION_TYPE") ?: if (isOfficial) "nightly" else "unofficial"
val versionRoot = System.getenv("VERSION_ROOT") ?: projectConfig.getProperty("versionRoot") ?: "3"
val microsoftAuthId = System.getenv("MICROSOFT_AUTH_ID") ?: ""
val microsoftAuthSecret = System.getenv("MICROSOFT_AUTH_SECRET") ?: ""
val curseForgeApiKey = System.getenv("CURSEFORGE_API_KEY") ?: ""
val launcherExe = System.getenv("HMCL_LAUNCHER_EXE")
val launcherExe = System.getenv("HMCL_LAUNCHER_EXE") ?: ""
version = "$versionRoot.$buildNumber"
val buildNumber = System.getenv("BUILD_NUMBER")?.toInt()
if (buildNumber != null) {
version = if (JenkinsUtils.IS_ON_CI && versionType == "dev") {
"$versionRoot.0.$buildNumber"
} else {
"$versionRoot.$buildNumber"
}
} else {
val shortCommit = System.getenv("GITHUB_SHA")?.lowercase()?.substring(0, 7)
version = if (shortCommit.isNullOrBlank()) {
"$versionRoot.SNAPSHOT"
} else if (isOfficial) {
"$versionRoot.dev-$shortCommit"
} else {
"$versionRoot.unofficial-$shortCommit"
}
}
dependencies {
implementation(project(":HMCLCore"))
@@ -43,7 +52,7 @@ dependencies {
implementation(libs.twelvemonkeys.imageio.webp)
implementation(libs.java.info)
if (launcherExe == null) {
if (launcherExe.isBlank()) {
implementation(libs.hmclauncher)
}
}
@@ -138,7 +147,6 @@ tasks.shadowJar {
"Microsoft-Auth-Secret" to microsoftAuthSecret,
"CurseForge-Api-Key" to curseForgeApiKey,
"Build-Channel" to versionType,
"Class-Path" to "pack200.jar",
"Add-Opens" to listOf(
"java.base/java.lang",
"java.base/java.lang.reflect",
@@ -162,7 +170,7 @@ tasks.shadowJar {
}
}
if (launcherExe != null) {
if (launcherExe.isNotBlank()) {
into("assets") {
from(file(launcherExe))
}
@@ -105,6 +105,10 @@ public final class Launcher extends Application {
return;
}
if (ConfigHolder.isUnsupportedVersion()) {
showAlert(AlertType.WARNING, i18n("fatal.config_unsupported_version"));
}
if (Metadata.HMCL_CURRENT_DIRECTORY.toString().indexOf('=') >= 0) {
Main.showWarningAndContinue(i18n("fatal.illegal_char"));
}
@@ -62,6 +62,21 @@ public final class Main {
createHMCLDirectories();
LOG.start(Metadata.HMCL_CURRENT_DIRECTORY.resolve("logs"));
if ("true".equalsIgnoreCase(System.getenv("HMCL_FORCE_GPU")))
System.getProperties().putIfAbsent("prism.forceGPU", "true");
String animationFrameRate = System.getenv("HMCL_ANIMATION_FRAME_RATE");
if (animationFrameRate != null) {
try {
if (Integer.parseInt(animationFrameRate) <= 0)
throw new NumberFormatException(animationFrameRate);
System.getProperties().putIfAbsent("javafx.animation.pulse", animationFrameRate);
} catch (NumberFormatException e) {
LOG.warning("Invalid animation frame rate: " + animationFrameRate);
}
}
checkDirectoryPath();
if (JavaRuntime.CURRENT_VERSION < 9)
@@ -39,7 +39,7 @@ public final class Metadata {
public static final String VERSION = System.getProperty("hmcl.version.override", JarUtils.getManifestAttribute("Implementation-Version", "@develop@"));
public static final int MINIMUM_REQUIRED_JAVA_VERSION = 8;
public static final int MINIMUM_SUPPORTED_JAVA_VERSION = 11;
public static final int MINIMUM_SUPPORTED_JAVA_VERSION = 17;
public static final String TITLE = NAME + " " + VERSION;
public static final String FULL_TITLE = FULL_NAME + " v" + VERSION;
@@ -59,6 +59,7 @@ import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.lang.ref.WeakReference;
import static javafx.application.Platform.runLater;
import static javafx.application.Platform.setImplicitExit;
@@ -125,6 +126,9 @@ public final class LauncherHelper {
}
private void launch0() {
// https://github.com/HMCL-dev/HMCL/pull/4121
PROCESSES.removeIf(it -> it.get() == null);
HMCLGameRepository repository = profile.getRepository();
DefaultDependencyManager dependencyManager = profile.getDependency();
AtomicReference<Version> version = new AtomicReference<>(MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion)));
@@ -156,8 +160,10 @@ public final class LauncherHelper {
}),
Task.composeAsync(() -> {
Renderer renderer = setting.getRenderer();
if (renderer != Renderer.DEFAULT && OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
Library lib = NativePatcher.getMesaLoader(java);
if (renderer != Renderer.DEFAULT
&& OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS
&& OperatingSystem.WINDOWS_VERSION != null) {
Library lib = NativePatcher.getWindowsMesaLoader(java, renderer, OperatingSystem.WINDOWS_VERSION);
if (lib == null)
return null;
File file = dependencyManager.getGameRepository().getLibraryFile(version.get(), lib);
@@ -209,7 +215,7 @@ public final class LauncherHelper {
}
}).thenAcceptAsync(process -> { // process is LaunchTask's result
if (scriptFile == null) {
PROCESSES.add(process);
PROCESSES.add(new WeakReference<>(process));
if (launcherVisibility == LauncherVisibility.CLOSE)
Launcher.stopApplication();
else
@@ -896,10 +902,10 @@ public final class LauncherHelper {
}
public static final Queue<ManagedProcess> PROCESSES = new ConcurrentLinkedQueue<>();
public static final Queue<WeakReference<ManagedProcess>> PROCESSES = new ConcurrentLinkedQueue<>();
public static void stopManagedProcesses() {
while (!PROCESSES.isEmpty())
Optional.ofNullable(PROCESSES.poll()).ifPresent(ManagedProcess::stop);
Optional.ofNullable(PROCESSES.poll()).map(WeakReference::get).ifPresent(ManagedProcess::stop);
}
}
@@ -30,6 +30,7 @@ import org.jackhuang.hmcl.util.io.NetworkUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -103,6 +104,7 @@ public final class OAuthServer extends NanoHTTPD implements OAuth.Session {
String html;
try {
html = IOUtils.readFullyAsString(OAuthServer.class.getResourceAsStream("/assets/microsoft_auth.html"))
.replace("%lang%", Locale.getDefault().toLanguageTag())
.replace("%close-page%", i18n("account.methods.microsoft.close_page"));
} catch (IOException e) {
LOG.error("Failed to load html", e);
@@ -56,6 +56,7 @@ public final class JavaManager {
}
public static final HMCLJavaRepository REPOSITORY = new HMCLJavaRepository(Metadata.HMCL_GLOBAL_DIRECTORY.resolve("java"));
public static final HMCLJavaRepository LOCAL_REPOSITORY = new HMCLJavaRepository(Metadata.HMCL_CURRENT_DIRECTORY.resolve("java"));
public static String getMojangJavaPlatform(Platform platform) {
if (platform.getOperatingSystem() == OperatingSystem.WINDOWS) {
@@ -254,16 +255,15 @@ public final class JavaManager {
}
}
private static int compareJavaVersion(JavaRuntime java1, JavaRuntime java2, GameJavaVersion suggestedJavaVersion) {
if (suggestedJavaVersion != null) {
boolean b1 = java1.getParsedVersion() == suggestedJavaVersion.getMajorVersion();
boolean b2 = java2.getParsedVersion() == suggestedJavaVersion.getMajorVersion();
private static JavaRuntime chooseJava(@Nullable JavaRuntime java1, JavaRuntime java2) {
if (java1 == null)
return java2;
if (b1 != b2)
return b1 ? 1 : -1;
}
return java1.getVersionNumber().compareTo(java2.getVersionNumber());
if (java1.getParsedVersion() != java2.getParsedVersion())
// Prefer the Java version that is closer to the game's recommended Java version
return java1.getParsedVersion() < java2.getParsedVersion() ? java1 : java2;
else
return java1.getVersionNumber().compareTo(java2.getVersionNumber()) >= 0 ? java1 : java2;
}
@Nullable
@@ -279,9 +279,6 @@ public final class JavaManager {
&& (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS || OperatingSystem.CURRENT_OS == OperatingSystem.MACOS)
&& (gameVersion == null || gameVersion.compareTo("1.6") < 0);
GameJavaVersion suggestedJavaVersion =
(version != null && gameVersion != null && gameVersion.compareTo("1.7.10") >= 0) ? version.getJavaVersion() : null;
JavaRuntime mandatory = null;
JavaRuntime suggested = null;
for (JavaRuntime java : javaRuntimes) {
@@ -309,15 +306,10 @@ public final class JavaManager {
}
if (!violationMandatory) {
if (mandatory == null) mandatory = java;
else if (compareJavaVersion(java, mandatory, suggestedJavaVersion) > 0)
mandatory = java;
mandatory = chooseJava(mandatory, java);
if (!violationSuggested) {
if (suggested == null) suggested = java;
else if (compareJavaVersion(java, suggested, suggestedJavaVersion) > 0)
suggested = java;
}
if (!violationSuggested)
suggested = chooseJava(suggested, java);
}
}
@@ -561,6 +553,10 @@ public final class JavaManager {
for (JavaRuntime java : REPOSITORY.getAllJava(platform)) {
javaRuntimes.put(java.getBinary(), java);
}
for (JavaRuntime java : LOCAL_REPOSITORY.getAllJava(platform)) {
javaRuntimes.put(java.getBinary(), java);
}
}
private static void searchAllOfficialJava(Map<Path, JavaRuntime> javaRuntimes, Path directory, boolean verify) {
@@ -50,6 +50,7 @@ import java.util.TreeMap;
public final class Config implements Observable {
public static final int CURRENT_VERSION = 2;
public static final int CURRENT_UI_VERSION = 0;
public static final Gson CONFIG_GSON = new GsonBuilder()
@@ -180,6 +181,9 @@ public final class Config implements Observable {
@SerializedName("promptedVersion")
private StringProperty promptedVersion = new SimpleStringProperty();
@SerializedName("acceptPreviewUpdate")
private BooleanProperty acceptPreviewUpdate = new SimpleBooleanProperty(false);
@SerializedName("_version")
private IntegerProperty configVersion = new SimpleIntegerProperty(0);
@@ -670,6 +674,18 @@ public final class Config implements Observable {
this.promptedVersion.set(promptedVersion);
}
public boolean isAcceptPreviewUpdate() {
return acceptPreviewUpdate.get();
}
public BooleanProperty acceptPreviewUpdateProperty() {
return acceptPreviewUpdate;
}
public void setAcceptPreviewUpdate(boolean acceptPreviewUpdate) {
this.acceptPreviewUpdate.set(acceptPreviewUpdate);
}
public ObservableMap<String, Object> getShownTips() {
return shownTips;
}
@@ -45,6 +45,7 @@ public final class ConfigHolder {
private static GlobalConfig globalConfigInstance;
private static boolean newlyCreated;
private static boolean ownerChanged = false;
private static boolean unsupportedVersion = false;
public static Config config() {
if (configInstance == null) {
@@ -72,6 +73,10 @@ public final class ConfigHolder {
return ownerChanged;
}
public static boolean isUnsupportedVersion() {
return unsupportedVersion;
}
public static void init() throws IOException {
if (configInstance != null) {
throw new IllegalStateException("Configuration is already loaded");
@@ -82,7 +87,8 @@ public final class ConfigHolder {
LOG.info("Config location: " + configLocation);
configInstance = loadConfig();
configInstance.addListener(source -> FileSaver.save(configLocation, configInstance.toJson()));
if (!unsupportedVersion)
configInstance.addListener(source -> FileSaver.save(configLocation, configInstance.toJson()));
globalConfigInstance = loadGlobalConfig();
globalConfigInstance.addListener(source -> FileSaver.save(GLOBAL_CONFIG_PATH, globalConfigInstance.toJson()));
@@ -162,7 +168,14 @@ public final class ConfigHolder {
if (deserialized == null) {
LOG.info("Config is empty");
} else {
ConfigUpgrader.upgradeConfig(deserialized, content);
int configVersion = deserialized.getConfigVersion();
if (configVersion < Config.CURRENT_VERSION) {
ConfigUpgrader.upgradeConfig(deserialized, content);
} else if (configVersion > Config.CURRENT_VERSION) {
unsupportedVersion = true;
LOG.warning(String.format("Current HMCL only support the configuration version up to %d. However, the version now is %d.", Config.CURRENT_VERSION, configVersion));
}
return deserialized;
}
} catch (JsonParseException e) {
@@ -31,8 +31,6 @@ final class ConfigUpgrader {
private ConfigUpgrader() {
}
private static final int CURRENT_VERSION = 2;
/**
* This method is for the compatibility with old HMCL versions.
*
@@ -42,17 +40,10 @@ final class ConfigUpgrader {
static void upgradeConfig(Config deserialized, String rawContent) {
int configVersion = deserialized.getConfigVersion();
if (configVersion == CURRENT_VERSION) {
if (configVersion >= Config.CURRENT_VERSION)
return;
}
if (configVersion > CURRENT_VERSION) {
LOG.warning(String.format("Current HMCL only support the configuration version up to %d. However, the version now is %d.", CURRENT_VERSION, configVersion));
deserialized.setConfigVersion(CURRENT_VERSION);
return;
}
LOG.info(String.format("Updating configuration from %d to %d.", configVersion, CURRENT_VERSION));
LOG.info(String.format("Updating configuration from %d to %d.", configVersion, Config.CURRENT_VERSION));
Map<?, ?> rawJson = Collections.unmodifiableMap(new Gson().<Map<?, ?>>fromJson(rawContent, Map.class));
if (configVersion < 1) {
@@ -100,6 +91,6 @@ final class ConfigUpgrader {
}
}
deserialized.setConfigVersion(CURRENT_VERSION);
deserialized.setConfigVersion(Config.CURRENT_VERSION);
}
}
@@ -59,7 +59,10 @@ public final class ProxyManager {
String password = config().getProxyPass();
if (username != null || password != null)
return new SimpleAuthenticator(username, password.toCharArray());
return new SimpleAuthenticator(
Lang.requireNonNullElse(username, ""),
Lang.requireNonNullElse(password, "").toCharArray()
);
else
return null;
} else
@@ -310,7 +310,7 @@ public final class Controllers {
}
}
if (JavaRuntime.CURRENT_VERSION < 10) {
if (JavaRuntime.CURRENT_VERSION < Metadata.MINIMUM_SUPPORTED_JAVA_VERSION) {
Number shownTipVersion = null;
try {
@@ -27,6 +27,7 @@ import javafx.beans.WeakInvalidationListener;
import javafx.beans.WeakListener;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.*;
import javafx.event.Event;
import javafx.event.EventDispatcher;
@@ -54,9 +55,8 @@ import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.Duration;
import javafx.util.StringConverter;
import org.glavo.png.PNGType;
import org.glavo.png.PNGWriter;
import org.glavo.png.javafx.PNGJavaFXUtils;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
import org.jackhuang.hmcl.util.*;
@@ -78,11 +78,16 @@ import javax.imageio.stream.ImageInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.ref.WeakReference;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@@ -779,6 +784,21 @@ public final class FXUtils {
}
}
public static Image loadWebPImage(InputStream input,
int requestedWidth, int requestedHeight,
boolean preserveRatio, boolean smooth) throws IOException {
WebPImageReaderSpi spi = new WebPImageReaderSpi();
ImageReader reader = spi.createReaderInstance(null);
BufferedImage bufferedImage;
try (ImageInputStream imageInput = ImageIO.createImageInputStream(input)) {
reader.setInput(imageInput, true, true);
bufferedImage = reader.read(0, reader.getDefaultReadParam());
} finally {
reader.dispose();
}
return SwingFXUtils.toFXImage(bufferedImage, requestedWidth, requestedHeight, preserveRatio, smooth);
}
public static Image loadImage(Path path) throws Exception {
try (InputStream input = Files.newInputStream(path)) {
if ("webp".equalsIgnoreCase(FileUtils.getExtension(path)))
@@ -792,6 +812,42 @@ public final class FXUtils {
}
}
public static Image loadImage(Path path,
int requestedWidth, int requestedHeight,
boolean preserveRatio, boolean smooth) throws Exception {
try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
String ext = FileUtils.getExtension(path).toLowerCase(Locale.ROOT);
if ("webp".equalsIgnoreCase(ext))
return loadWebPImage(Channels.newInputStream(channel),
requestedWidth, requestedHeight, preserveRatio, smooth);
if (!IMAGE_EXTENSIONS.contains(ext)) {
byte[] header = new byte[12];
ByteBuffer buffer = ByteBuffer.wrap(header);
//noinspection StatementWithEmptyBody
while (buffer.hasRemaining() && channel.read(buffer) > 0) {
}
channel.position(0L);
if (!buffer.hasRemaining()) {
// WebP File
if (header[0] == 'R' && header[1] == 'I' && header[2] == 'F' && header[3] == 'F' &&
header[8] == 'W' && header[9] == 'E' && header[10] == 'B' && header[11] == 'P') {
return loadWebPImage(Channels.newInputStream(channel),
requestedWidth, requestedHeight, preserveRatio, smooth);
}
}
}
Image image = new Image(Channels.newInputStream(channel),
requestedWidth, requestedHeight,
preserveRatio, smooth);
if (image.isError())
throw image.getException();
return image;
}
}
public static Image loadImage(URL url) throws Exception {
URLConnection connection = NetworkUtils.createConnection(url);
if (connection instanceof HttpURLConnection) {
@@ -851,15 +907,37 @@ public final class FXUtils {
}
}
/**
* Load image from the internet. It will cache the data of images for the further usage.
* The cached data will be deleted when HMCL is closed or hidden.
*
* @param url the url of image. The image resource should be a file on the internet.
* @return the image resource within the jar.
*/
public static Image newRemoteImage(String url) {
return newRemoteImage(url, 0, 0, false, false, false);
public static Task<Image> getRemoteImageTask(String url, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
return Task.composeAsync(() -> {
Path currentPath = remoteImageCache.get(url);
if (currentPath != null) {
if (Files.isReadable(currentPath))
return Task.completed(currentPath);
// The file is unavailable or unreadable.
remoteImageCache.remove(url);
try {
Files.deleteIfExists(currentPath);
} catch (IOException e) {
LOG.warning("An exception encountered while deleting broken cached image file.", e);
}
}
Path newPath = Files.createTempFile("hmcl-net-resource-cache-", ".cache");
return new FileDownloadTask(NetworkUtils.toURL(url), newPath.toFile())
.thenSupplyAsync(() -> {
Path otherPath = remoteImageCache.putIfAbsent(url, newPath);
if (otherPath == null)
return newPath;
else {
// The image has been loaded in another task. Delete the image here in order not to pollute the tmp folder.
Files.delete(newPath);
return otherPath;
}
});
}).thenApplyAsync(path -> loadImage(path, requestedWidth, requestedHeight, preserveRatio, smooth));
}
/**
@@ -877,52 +955,17 @@ public final class FXUtils {
* the specified bounding box
* @return the image resource within the jar.
*/
public static Image newRemoteImage(String url, double requestedWidth, double requestedHeight, boolean preserveRatio, boolean smooth, boolean backgroundLoading) {
Path currentPath = remoteImageCache.get(url);
if (currentPath != null) {
if (Files.isReadable(currentPath)) {
try (InputStream inputStream = Files.newInputStream(currentPath)) {
return new Image(inputStream, requestedWidth, requestedHeight, preserveRatio, smooth);
} catch (IOException e) {
LOG.warning("An exception encountered while reading data from cached image file.", e);
}
}
// The file is unavailable or unreadable.
remoteImageCache.remove(url);
try {
Files.deleteIfExists(currentPath);
} catch (IOException e) {
LOG.warning("An exception encountered while deleting broken cached image file.", e);
}
}
Image image = new Image(url, requestedWidth, requestedHeight, preserveRatio, smooth, backgroundLoading);
image.progressProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.doubleValue() >= 1.0 && !image.isError() && image.getPixelReader() != null && image.getWidth() > 0.0 && image.getHeight() > 0.0) {
Task.runAsync(() -> {
Path newPath = Files.createTempFile("hmcl-net-resource-cache-", ".cache");
try ( // Make sure the file is released from JVM before we put the path into remoteImageCache.
OutputStream outputStream = Files.newOutputStream(newPath);
PNGWriter writer = new PNGWriter(outputStream, PNGType.RGBA, PNGWriter.DEFAULT_COMPRESS_LEVEL)
) {
writer.write(PNGJavaFXUtils.asArgbImage(image));
} catch (IOException e) {
try {
Files.delete(newPath);
} catch (IOException e2) {
e2.addSuppressed(e);
throw e2;
}
throw e;
public static ObservableValue<Image> newRemoteImage(String url, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
SimpleObjectProperty<Image> image = new SimpleObjectProperty<>();
getRemoteImageTask(url, requestedWidth, requestedHeight, preserveRatio, smooth)
.whenComplete(Schedulers.javafx(), (result, exception) -> {
if (exception == null) {
image.set(result);
} else {
LOG.warning("An exception encountered while loading remote image: " + url, exception);
}
if (remoteImageCache.putIfAbsent(url, newPath) != null) {
Files.delete(newPath); // The image has been loaded in another task. Delete the image here in order not to pollute the tmp folder.
}
}).start();
}
});
})
.start();
return image;
}
@@ -22,6 +22,7 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import org.jackhuang.hmcl.util.StringUtils;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
@@ -159,28 +160,19 @@ public final class HTMLRenderer {
private void appendImage(Node node) {
String src = node.absUrl("src");
URI imageUri = null;
try {
if (!src.isEmpty())
imageUri = URI.create(src);
} catch (Exception ignored) {
}
String alt = node.attr("alt");
if (imageUri != null) {
URI uri = URI.create(src);
if (StringUtils.isNotBlank(src)) {
String widthAttr = node.attr("width");
String heightAttr = node.attr("height");
double width = 0;
double height = 0;
int width = 0;
int height = 0;
if (!widthAttr.isEmpty() && !heightAttr.isEmpty()) {
try {
width = Double.parseDouble(widthAttr);
height = Double.parseDouble(heightAttr);
width = (int) Double.parseDouble(widthAttr);
height = (int) Double.parseDouble(heightAttr);
} catch (NumberFormatException ignored) {
}
@@ -190,10 +182,12 @@ public final class HTMLRenderer {
}
}
Image image = FXUtils.newRemoteImage(uri.toString(), width, height, true, true, false);
if (image.isError()) {
LOG.warning("Failed to load image: " + uri, image.getException());
} else {
try {
Image image = FXUtils.getRemoteImageTask(src, width, height, true, true)
.run();
if (image == null)
throw new AssertionError("Image loading task returned null");
ImageView imageView = new ImageView(image);
if (hyperlink != null) {
URI target = resolveLink(hyperlink);
@@ -204,6 +198,8 @@ public final class HTMLRenderer {
}
children.add(imageView);
return;
} catch (Throwable e) {
LOG.warning("Failed to load image: " + src, e);
}
}
@@ -22,6 +22,7 @@ import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@@ -312,7 +313,9 @@ public class InstallerItem extends Control {
private static final class InstallerItemSkin extends SkinBase<InstallerItem> {
private static final PseudoClass LIST_ITEM = PseudoClass.getPseudoClass("list-item");
private static final PseudoClass CARD = PseudoClass.getPseudoClass("card");
private static final WeakListenerHolder holder = new WeakListenerHolder();
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private final ChangeListener<Number> holder;
InstallerItemSkin(InstallerItem control) {
super(control);
@@ -320,9 +323,14 @@ public class InstallerItem extends Control {
Pane pane;
if (control.style == Style.CARD) {
pane = new VBox();
holder.add(FXUtils.onWeakChange(pane.widthProperty(), v -> FXUtils.setLimitHeight(pane, v.doubleValue() * 0.7)));
if (FXUtils.JAVAFX_MAJOR_VERSION == 8)
holder = FXUtils.onWeakChange(pane.widthProperty(), v -> FXUtils.setLimitHeight(pane, v.doubleValue() * 0.7));
else
holder = FXUtils.onWeakChangeAndOperate(pane.widthProperty(), v -> FXUtils.setLimitHeight(pane, v.doubleValue() * 0.7));
} else {
pane = new HBox();
holder = null;
}
pane.getStyleClass().add("installer-item");
RipplerContainer container = new RipplerContainer(pane);
@@ -48,11 +48,22 @@ public final class UpgradeDialog extends JFXDialogLayout {
setBody(new ProgressIndicator());
String url = CHANGELOG_URL + remoteVersion.getChannel().channelName + ".html";
boolean isPreview = remoteVersion.isPreview();
Task.supplyAsync(Schedulers.io(), () -> {
Document document = Jsoup.parse(new URL(url), 30 * 1000);
Node node = document.selectFirst("#nowchange");
String id = null;
Node node = null;
if (isPreview) {
id = "nowpreview";
node = document.selectFirst("#" + id);
}
if (node == null) {
id = "nowchange";
node = document.selectFirst("#" + id);
}
if (node == null || !"h1".equals(node.nodeName()))
throw new IOException("Cannot find #nowchange in document");
throw new IOException("Cannot find current changelog in document");
HTMLRenderer renderer = new HTMLRenderer(uri -> {
LOG.info("Open link: " + uri);
@@ -60,7 +71,7 @@ public final class UpgradeDialog extends JFXDialogLayout {
});
do {
if ("h1".equals(node.nodeName()) && !"nowchange".equals(node.attr("id"))) {
if ("h1".equals(node.nodeName()) && !id.equals(node.attr("id"))) {
break;
}
renderer.appendNode(node);
@@ -78,15 +78,22 @@ public class AccountAdvancedListItem extends AdvancedListItem {
setActionButtonVisible(false);
setOnScroll(event -> {
double deltaY = event.getDeltaY();
if (deltaY == 0)
return;
Account current = account.get();
if (current == null) return;
ObservableList<Account> accounts = Accounts.getAccounts();
int currentIndex = accounts.indexOf(account.get());
if (event.getDeltaY() > 0) { // up
int currentIndex = accounts.indexOf(current);
if (currentIndex < 0) return;
if (deltaY > 0) // up
currentIndex--;
} else { // down
else // down
currentIndex++;
}
Accounts.setSelectedAccount(accounts.get((currentIndex + accounts.size()) % accounts.size()));
});
}
@@ -267,7 +267,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
}).executor(true);
};
if (factory instanceof OfflineAccountFactory && username != null && !USERNAME_CHECKER_PATTERN.matcher(username).matches()) {
if (factory instanceof OfflineAccountFactory && username != null && (!USERNAME_CHECKER_PATTERN.matcher(username).matches() || username.length() > 16)) {
JFXButton btnYes = new JFXButton(i18n("button.ok"));
btnYes.getStyleClass().add("dialog-error");
btnYes.setOnAction(e -> doCreate.run());
@@ -30,8 +30,7 @@ public class TransitionPane extends StackPane implements AnimationHandler {
private Duration duration;
private Node previousNode, currentNode;
{
currentNode = getChildren().stream().findFirst().orElse(null);
public TransitionPane() {
FXUtils.setOverflowHidden(this);
}
@@ -91,8 +90,12 @@ public class TransitionPane extends StackPane implements AnimationHandler {
private void updateContent(Node newView) {
if (getWidth() > 0 && getHeight() > 0) {
previousNode = currentNode;
if (previousNode == null)
previousNode = EMPTY_PANE;
if (previousNode == null) {
if (getChildren().isEmpty())
previousNode = EMPTY_PANE;
else
previousNode = getChildren().get(0);
}
} else
previousNode = EMPTY_PANE;
@@ -98,7 +98,7 @@ public final class MessageDialogPane extends HBox {
{
StackPane titlePane = new StackPane();
titlePane.getStyleClass().addAll("jfx-layout-heading", "title");
titlePane.getChildren().setAll(new Label(title != null ? title : i18n("message.info")));
titlePane.getChildren().setAll(new Label(title != null ? title : type.getDisplayName()));
StackPane content = new StackPane();
content.getStyleClass().add("jfx-layout-body");
@@ -261,6 +261,7 @@ public final class TaskListPane extends StackPane {
case "hmcl.install.fabric": message = i18n("install.installer.install", i18n("install.installer.fabric") + " " + stageValue); break;
case "hmcl.install.fabric-api": message = i18n("install.installer.install", i18n("install.installer.fabric-api") + " " + stageValue); break;
case "hmcl.install.quilt": message = i18n("install.installer.install", i18n("install.installer.quilt") + " " + stageValue); break;
case "hmcl.install.quilt-api": message = i18n("install.installer.install", i18n("install.installer.quilt-api") + " " + stageValue); break;
default: message = i18n(stageKey); break;
}
// @formatter:on
@@ -198,6 +198,8 @@ public class DecoratorController {
private Background getBackground() {
EnumBackgroundImage imageType = config().getBackgroundImageType();
if (imageType == null)
imageType = EnumBackgroundImage.DEFAULT;
Image image = null;
switch (imageType) {
@@ -124,7 +124,7 @@ public abstract class AbstractInstallersPage extends Control implements WizardPa
libraryPane.setVgap(16);
libraryPane.setHgap(16);
if (libraries.length <= 8) {
if (FXUtils.JAVAFX_MAJOR_VERSION < 25 && libraries.length <= 8) {
BorderPane.setMargin(libraryPane, new Insets(16, 0, 16, 0));
root.setCenter(libraryPane);
} else {
@@ -133,6 +133,9 @@ public abstract class AbstractInstallersPage extends Control implements WizardPa
scrollPane.setFitToHeight(true);
BorderPane.setMargin(scrollPane, new Insets(16, 0, 16, 0));
root.setCenter(scrollPane);
if (libraries.length <= 8)
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
}
}
@@ -18,11 +18,11 @@
package org.jackhuang.hmcl.ui.download;
import javafx.scene.Node;
import org.jackhuang.hmcl.game.ModpackHelper;
import org.jackhuang.hmcl.game.ManuallyCreatedModpackException;
import org.jackhuang.hmcl.mod.ModpackCompletionException;
import org.jackhuang.hmcl.game.ModpackHelper;
import org.jackhuang.hmcl.mod.MismatchedModpackTypeException;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.ModpackCompletionException;
import org.jackhuang.hmcl.mod.UnsupportedModpackException;
import org.jackhuang.hmcl.mod.server.ServerModpackManifest;
import org.jackhuang.hmcl.setting.Profile;
@@ -102,7 +102,7 @@ public class ModpackInstallWizardProvider implements WizardProvider {
} catch (UnsupportedModpackException | ManuallyCreatedModpackException e) {
Controllers.dialog(i18n("modpack.unsupported"), i18n("message.error"), MessageType.ERROR);
} catch (MismatchedModpackTypeException e) {
Controllers.dialog(i18n("modpack.mismatched_type"), i18n("message.error"), MessageType.ERROR);
Controllers.dialog(i18n("modpack.mismatched_type", e.getRequired(), e.getFound()), i18n("message.error"), MessageType.ERROR);
} catch (IOException e) {
Controllers.dialog(i18n("modpack.invalid"), i18n("message.error"), MessageType.ERROR);
}
@@ -124,6 +124,7 @@ public class DownloadSettingsPage extends StackPane {
{
HBox hbox = new HBox(8);
hbox.setStyle("-fx-view-order: -1;"); // prevent the indicator from being covered by the hint
hbox.setAlignment(Pos.CENTER);
hbox.setPadding(new Insets(0, 0, 0, 30));
hbox.disableProperty().bind(config().autoDownloadThreadsProperty());
@@ -62,12 +62,12 @@ import org.jackhuang.hmcl.ui.versions.Versions;
import org.jackhuang.hmcl.upgrade.RemoteVersion;
import org.jackhuang.hmcl.upgrade.UpdateChecker;
import org.jackhuang.hmcl.upgrade.UpdateHandler;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.javafx.BindingMapping;
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.SINE;
@@ -197,15 +197,17 @@ public final class MainPage extends StackPane implements DecoratorPage {
launchPane.setMaxWidth(230);
launchPane.setMaxHeight(55);
launchPane.setOnScroll(event -> {
int index = IntStream.range(0, versions.size())
.filter(i -> versions.get(i).getId().equals(getCurrentGame()))
.findFirst().orElse(-1);
double deltaY = event.getDeltaY();
if (deltaY == 0)
return;
String currentId = getCurrentGame();
int index = Lang.indexWhere(versions, instance -> instance.getId().equals(currentId));
if (index < 0) return;
if (event.getDeltaY() > 0) {
if (deltaY > 0) // up
index--;
} else {
else // down
index++;
}
profile.setSelectedVersion(versions.get((index + versions.size()) % versions.size()).getId());
});
StackPane.setAlignment(launchPane, Pos.BOTTOM_RIGHT);
@@ -106,9 +106,12 @@ public final class SettingsPage extends SettingsView {
chkUpdateStable.setUserData(UpdateChannel.STABLE);
ObjectProperty<UpdateChannel> updateChannel = selectedItemPropertyFor(updateChannelGroup, UpdateChannel.class);
updateChannel.set(UpdateChannel.getChannel());
updateChannel.addListener((a, b, newValue) -> {
UpdateChecker.requestCheckUpdate(newValue);
});
InvalidationListener checkUpdateListener = e -> {
UpdateChecker.requestCheckUpdate(updateChannel.get(), previewPane.isSelected());
};
updateChannel.addListener(checkUpdateListener);
previewPane.selectedProperty().addListener(checkUpdateListener);
// ====
}
@@ -37,6 +37,7 @@ import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.construct.ComponentList;
import org.jackhuang.hmcl.ui.construct.ComponentSublist;
import org.jackhuang.hmcl.ui.construct.MultiFileItem;
import org.jackhuang.hmcl.ui.construct.OptionToggleButton;
import org.jackhuang.hmcl.util.i18n.I18n;
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
@@ -56,6 +57,7 @@ public abstract class SettingsView extends StackPane {
protected final JFXRadioButton chkUpdateStable;
protected final JFXRadioButton chkUpdateDev;
protected final JFXButton btnUpdate;
protected final OptionToggleButton previewPane;
protected final ScrollPane scroll;
public SettingsView() {
@@ -145,6 +147,15 @@ public abstract class SettingsView extends StackPane {
settingsPane.getContent().add(updatePane);
}
{
previewPane = new OptionToggleButton();
previewPane.setTitle(i18n("update.preview"));
previewPane.selectedProperty().bindBidirectional(config().acceptPreviewUpdateProperty());
FXUtils.installFastTooltip(previewPane, i18n("update.preview.tooltip"));
settingsPane.getContent().add(previewPane);
}
{
fileCommonLocation = new MultiFileItem<>();
fileCommonLocationSublist = new ComponentSublist();
@@ -18,8 +18,9 @@ import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.construct.*;
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.platform.Platform;
import org.jetbrains.annotations.Nullable;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Locale;
@@ -52,7 +53,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
private final MultiFileItem.FileOption<NativesDirectoryType> nativesDirCustomOption;
private final JFXComboBox<Renderer> cboRenderer;
public AdvancedVersionSettingPage(Profile profile, String versionId, VersionSetting versionSetting) {
public AdvancedVersionSettingPage(Profile profile, @Nullable String versionId, VersionSetting versionSetting) {
this.profile = profile;
this.versionId = versionId;
this.versionSetting = versionSetting;
@@ -239,8 +240,27 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
useNativeOpenALPane.selectedProperty().bindBidirectional(versionSetting.useNativeOpenALProperty());
nativesDirItem.selectedDataProperty().bindBidirectional(versionSetting.nativesDirTypeProperty());
nativesDirSublist.subtitleProperty().bind(Bindings.createStringBinding(() -> Paths.get(profile.getRepository().getRunDirectory(versionId).getAbsolutePath() + "/natives").normalize().toString(),
versionSetting.nativesDirProperty(), versionSetting.nativesDirTypeProperty()));
nativesDirSublist.subtitleProperty().bind(Bindings.createStringBinding(() -> {
if (versionSetting.getNativesDirType() == NativesDirectoryType.VERSION_FOLDER) {
String nativesDirName = "natives-" + Platform.SYSTEM_PLATFORM;
if (versionId == null) {
return String.format("%s/%s/%s",
profile.getRepository().getBaseDirectory().toPath().resolve("versions").toAbsolutePath().normalize(),
i18n("settings.advanced.natives_directory.default.version_id"),
nativesDirName
);
} else {
return profile.getRepository().getVersionRoot(versionId).toPath()
.toAbsolutePath().normalize()
.resolve(nativesDirName)
.toString();
}
} else if (versionSetting.getNativesDirType() == NativesDirectoryType.CUSTOM) {
return versionSetting.getNativesDir();
} else {
return null;
}
}, versionSetting.nativesDirProperty(), versionSetting.nativesDirTypeProperty()));
}
void unbindProperties() {
@@ -229,6 +229,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
}
private static class ModDownloadListPageSkin extends SkinBase<DownloadListPage> {
private final JFXListView<RemoteMod> listView = new JFXListView<>();
protected ModDownloadListPageSkin(DownloadListPage control) {
super(control);
@@ -449,6 +450,8 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
boolean disableNext = disableAll || pageOffset == pageCount - 1;
nextPageButton.setDisable(disableNext);
lastPageButton.setDisable(disableNext);
listView.scrollTo(0);
};
FXUtils.onChange(control.pageCount, pageCountN -> {
@@ -504,7 +507,6 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
}
});
JFXListView<RemoteMod> listView = new JFXListView<>();
spinnerPane.setContent(listView);
Bindings.bindContent(listView.getItems(), getSkinnable().items);
FXUtils.onClicked(listView, () -> {
@@ -540,7 +542,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
.collect(Collectors.toList()));
if (StringUtils.isNotBlank(dataItem.getIconUrl())) {
imageView.setImage(FXUtils.newRemoteImage(dataItem.getIconUrl(), 40, 40, true, true, true));
imageView.imageProperty().bind(FXUtils.newRemoteImage(dataItem.getIconUrl(), 40, 40, true, true));
}
}
});
@@ -220,7 +220,7 @@ public class DownloadPage extends Control implements DecoratorPage {
{
ImageView imageView = new ImageView();
if (StringUtils.isNotBlank(getSkinnable().addon.getIconUrl())) {
imageView.setImage(FXUtils.newRemoteImage(getSkinnable().addon.getIconUrl(), 40, 40, true, true, true));
imageView.imageProperty().bind(FXUtils.newRemoteImage(getSkinnable().addon.getIconUrl(), 40, 40, true, true));
}
descriptionPane.getChildren().add(FXUtils.limitingSize(imageView, 40, 40));
@@ -359,7 +359,7 @@ public class DownloadPage extends Control implements DecoratorPage {
.collect(Collectors.toList()));
if (StringUtils.isNotBlank(addon.getIconUrl())) {
imageView.setImage(FXUtils.newRemoteImage(addon.getIconUrl(), 40, 40, true, true, true));
imageView.imageProperty().bind(FXUtils.newRemoteImage(addon.getIconUrl(), 40, 40, true, true));
}
} else {
content.setTitle(i18n("mods.broken_dependency.title"));
@@ -142,7 +142,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
toolbarNormal.getChildren().setAll(
createToolbarButton2(i18n("button.refresh"), SVG.REFRESH, skinnable::refresh),
createToolbarButton2(i18n("mods.add"), SVG.ADD, skinnable::add),
createToolbarButton2(i18n("folder.mod"), SVG.FOLDER_OPEN, skinnable::openModFolder),
createToolbarButton2(i18n("button.reveal_dir"), SVG.FOLDER_OPEN, skinnable::openModFolder),
createToolbarButton2(i18n("mods.check_updates"), SVG.UPDATE, skinnable::checkUpdates),
createToolbarButton2(i18n("download"), SVG.DOWNLOAD, skinnable::download),
createToolbarButton2(i18n("search"), SVG.SEARCH, () -> changeToolbar(searchBar))
@@ -361,14 +361,27 @@ public final class WorldInfoPage extends SpinnerPane {
playerGameTypePane.setRight(gameTypeBox);
Tag tag = player.get("playerGameType");
Tag hardcoreTag = dataTag.get("hardcore");
boolean isHardcore = hardcoreTag instanceof ByteTag && ((ByteTag) hardcoreTag).getValue() == 1;
if (tag instanceof IntTag) {
IntTag intTag = (IntTag) tag;
GameType gameType = GameType.of(intTag.getValue());
GameType gameType = GameType.of(intTag.getValue(), isHardcore);
if (gameType != null) {
gameTypeBox.setValue(gameType);
gameTypeBox.valueProperty().addListener((o, oldValue, newValue) -> {
if (newValue != null) {
intTag.setValue(newValue.ordinal());
if (newValue == GameType.HARDCORE) {
intTag.setValue(0); // survival (hardcore worlds are survival+hardcore flag)
if (hardcoreTag instanceof ByteTag) {
((ByteTag) hardcoreTag).setValue((byte) 1);
}
} else {
intTag.setValue(newValue.ordinal());
if (hardcoreTag instanceof ByteTag) {
((ByteTag) hardcoreTag).setValue((byte) 0);
}
}
saveLevelDat();
}
});
@@ -606,12 +619,13 @@ public final class WorldInfoPage extends SpinnerPane {
}
private enum GameType {
SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR;
SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR, HARDCORE;
static final ObservableList<GameType> items = FXCollections.observableList(Arrays.asList(values()));
static GameType of(int d) {
return d >= 0 && d <= items.size() ? items.get(d) : null;
static GameType of(int d, boolean hardcore) {
if (hardcore && d == 0) return HARDCORE; // hardcore + survival
return d >= 0 && d < 4 ? items.get(d) : null;
}
@Override
@@ -18,15 +18,9 @@
package org.jackhuang.hmcl.upgrade;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.util.Pack200Utils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.tukaani.xz.XZInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.jar.JarOutputStream;
class HMCLDownloadTask extends FileDownloadTask {
@@ -47,15 +41,6 @@ class HMCLDownloadTask extends FileDownloadTask {
switch (archiveFormat) {
case JAR:
break;
case PACK_XZ:
byte[] raw = Files.readAllBytes(target);
try (InputStream in = new XZInputStream(new ByteArrayInputStream(raw));
JarOutputStream out = new JarOutputStream(Files.newOutputStream(target))) {
Pack200Utils.unpack(in, out);
}
break;
default:
throw new IllegalArgumentException("Unknown format: " + archiveFormat);
}
@@ -21,28 +21,23 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck;
import org.jackhuang.hmcl.util.Pack200Utils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import java.io.IOException;
import java.util.Optional;
public class RemoteVersion {
public final class RemoteVersion {
public static RemoteVersion fetch(UpdateChannel channel, String url) throws IOException {
public static RemoteVersion fetch(UpdateChannel channel, boolean preview, String url) throws IOException {
try {
JsonObject response = JsonUtils.fromNonNullJson(NetworkUtils.doGet(NetworkUtils.toURL(url)), JsonObject.class);
String version = Optional.ofNullable(response.get("version")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("version is missing"));
String jarUrl = Optional.ofNullable(response.get("jar")).map(JsonElement::getAsString).orElse(null);
String jarHash = Optional.ofNullable(response.get("jarsha1")).map(JsonElement::getAsString).orElse(null);
String packXZUrl = Optional.ofNullable(response.get("packxz")).map(JsonElement::getAsString).orElse(null);
String packXZHash = Optional.ofNullable(response.get("packxzsha1")).map(JsonElement::getAsString).orElse(null);
boolean force = Optional.ofNullable(response.get("force")).map(JsonElement::getAsBoolean).orElse(false);
if (Pack200Utils.isSupported() && packXZUrl != null && packXZHash != null) {
return new RemoteVersion(channel, version, packXZUrl, Type.PACK_XZ, new IntegrityCheck("SHA-1", packXZHash), force);
} else if (jarUrl != null && jarHash != null) {
return new RemoteVersion(channel, version, jarUrl, Type.JAR, new IntegrityCheck("SHA-1", jarHash), force);
if (jarUrl != null && jarHash != null) {
return new RemoteVersion(channel, version, jarUrl, Type.JAR, new IntegrityCheck("SHA-1", jarHash), preview, force);
} else {
throw new IOException("No download url is available");
}
@@ -56,14 +51,16 @@ public class RemoteVersion {
private final String url;
private final Type type;
private final IntegrityCheck integrityCheck;
private final boolean preview;
private final boolean force;
public RemoteVersion(UpdateChannel channel, String version, String url, Type type, IntegrityCheck integrityCheck, boolean force) {
public RemoteVersion(UpdateChannel channel, String version, String url, Type type, IntegrityCheck integrityCheck, boolean preview, boolean force) {
this.channel = channel;
this.version = version;
this.url = url;
this.type = type;
this.integrityCheck = integrityCheck;
this.preview = preview;
this.force = force;
}
@@ -87,6 +84,10 @@ public class RemoteVersion {
return integrityCheck;
}
public boolean isPreview() {
return preview;
}
public boolean isForce() {
return force;
}
@@ -97,7 +98,6 @@ public class RemoteVersion {
}
public enum Type {
PACK_XZ,
JAR
}
}
@@ -27,14 +27,15 @@ import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jackhuang.hmcl.util.versioning.VersionNumber;
import java.io.IOException;
import java.util.LinkedHashMap;
import static org.jackhuang.hmcl.util.Lang.mapOf;
import static org.jackhuang.hmcl.util.Lang.thread;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.util.Lang.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
public final class UpdateChecker {
private UpdateChecker() {}
private UpdateChecker() {
}
private static final ObjectProperty<RemoteVersion> latestVersion = new SimpleObjectProperty<>();
private static final BooleanBinding outdated = Bindings.createBooleanBinding(
@@ -55,7 +56,7 @@ public final class UpdateChecker {
private static final ReadOnlyBooleanWrapper checkingUpdate = new ReadOnlyBooleanWrapper(false);
public static void init() {
requestCheckUpdate(UpdateChannel.getChannel());
requestCheckUpdate(UpdateChannel.getChannel(), config().isAcceptPreviewUpdate());
}
public static RemoteVersion getLatestVersion() {
@@ -82,16 +83,17 @@ public final class UpdateChecker {
return checkingUpdate.getReadOnlyProperty();
}
private static RemoteVersion checkUpdate(UpdateChannel channel) throws IOException {
private static RemoteVersion checkUpdate(UpdateChannel channel, boolean preview) throws IOException {
if (!IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK && !IntegrityChecker.isSelfVerified()) {
throw new IOException("Self verification failed");
}
String url = NetworkUtils.withQuery(Metadata.HMCL_UPDATE_URL, mapOf(
pair("version", Metadata.VERSION),
pair("channel", channel.channelName)));
LinkedHashMap<String, String> query = new LinkedHashMap<>();
query.put("version", Metadata.VERSION);
query.put("channel", preview ? channel.channelName + "-preview" : channel.channelName);
return RemoteVersion.fetch(channel, url);
String url = NetworkUtils.withQuery(Metadata.HMCL_UPDATE_URL, query);
return RemoteVersion.fetch(channel, preview, url);
}
private static boolean isDevelopmentVersion(String version) {
@@ -99,7 +101,7 @@ public final class UpdateChecker {
version.contains("SNAPSHOT"); // eg. 3.5.SNAPSHOT
}
public static void requestCheckUpdate(UpdateChannel channel) {
public static void requestCheckUpdate(UpdateChannel channel, boolean preview) {
Platform.runLater(() -> {
if (isCheckingUpdate())
return;
@@ -108,8 +110,8 @@ public final class UpdateChecker {
thread(() -> {
RemoteVersion result = null;
try {
result = checkUpdate(channel);
LOG.info("Latest version (" + channel + ") is " + result);
result = checkUpdate(channel, preview);
LOG.info("Latest version (" + channel + ", preview=" + preview + ") is " + result);
} catch (IOException e) {
LOG.warning("Failed to check for update", e);
}
@@ -30,9 +30,9 @@ public final class ChunkBaseApp {
private static final GameVersionNumber MIN_GAME_VERSION = GameVersionNumber.asGameVersion("1.7");
private static final String[] SEED_MAP_GAME_VERSIONS = {
"1.21.5", "1.21.4", "1.21.2", "1.21", "1.20", "1.19.3", "1.19",
"1.18", "1.17", "1.16", "1.15", "1.14", "1.13", "1.12", "1.11",
"1.10", "1.9", "1.8", "1.7"
"1.21.6", "1.21.5", "1.21.4", "1.21.2", "1.21", "1.20", "1.19.3",
"1.19", "1.18", "1.17", "1.16", "1.15", "1.14", "1.13", "1.12",
"1.11", "1.10", "1.9", "1.8", "1.7"
};
public static final String[] STRONGHOLD_FINDER_GAME_VERSIONS = {
@@ -26,7 +26,10 @@ import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.java.JavaRuntime;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.platform.Platform;
import org.jackhuang.hmcl.util.platform.windows.WindowsVersion;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -178,7 +181,19 @@ public final class NativePatcher {
return version.setLibraries(newLibraries);
}
public static Library getMesaLoader(JavaRuntime javaVersion) {
return getNatives(javaVersion.getPlatform()).get("mesa-loader");
public static @Nullable Library getWindowsMesaLoader(@NotNull JavaRuntime javaVersion, @NotNull Renderer renderer, @NotNull WindowsVersion windowsVersion) {
if (renderer == Renderer.DEFAULT)
return null;
if (windowsVersion.compareTo(WindowsVersion.WINDOWS_10) >= 0) {
return getNatives(javaVersion.getPlatform()).get("mesa-loader");
} else if (windowsVersion.compareTo(WindowsVersion.WINDOWS_7) >= 0) {
if (renderer == Renderer.LLVMPIPE)
return getNatives(javaVersion.getPlatform()).get("software-renderer-loader");
else
return null;
} else {
return null;
}
}
}
@@ -120,5 +120,43 @@ public final class SwingFXUtils {
pw.setPixels(0, 0, bw, bh, pf, data, offset, scan);
return wimg;
}
public static WritableImage toFXImage(BufferedImage bimg, double requestedWidth, double requestedHeight, boolean preserveRatio, boolean smooth) {
if (requestedWidth <= 0. || requestedHeight <= 0.) {
return toFXImage(bimg, null);
}
int width = (int) requestedWidth;
int height = (int) requestedHeight;
// Calculate actual dimensions if preserveRatio is true
if (preserveRatio) {
double originalWidth = bimg.getWidth();
double originalHeight = bimg.getHeight();
double scaleX = requestedWidth / originalWidth;
double scaleY = requestedHeight / originalHeight;
double scale = Math.min(scaleX, scaleY);
width = (int) (originalWidth * scale);
height = (int) (originalHeight * scale);
}
// Create scaled BufferedImage
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D g2d = scaledImage.createGraphics();
try {
if (smooth) {
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
g2d.drawImage(bimg, 0, 0, width, height, null);
} finally {
g2d.dispose();
}
return toFXImage(scaledImage, null);
}
}
@@ -106,14 +106,26 @@
-fx-background-color: -fx-base-darker-color;
}
.memory-used:disabled {
-fx-opacity: 0.4;
}
.memory-allocate {
-fx-background-color: derive(-fx-base-color, 100%);
}
.memory-allocate:disabled {
-fx-opacity: 0.4;
}
.memory-total {
-fx-background-color: -fx-base-rippler-color;
}
.memory-total:disabled {
-fx-opacity: 0.4;
}
.update-label {
-fx-text-fill: red;
}
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2026 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
@@ -21,7 +21,7 @@
about=About
about.copyright=Copyright
about.copyright.statement=Copyright © 2025 huangyuhui
about.copyright.statement=Copyright © 2013-2026 huangyuhui and contributors.
about.author=Author
about.author.statement=bilibili @huanghongxun
about.claim=EULA
@@ -124,7 +124,7 @@ account.methods.microsoft.purchase=Buy Minecraft
account.methods.microsoft.snapshot=You are using an unofficial build of HMCL. Please download the official build to log in.
account.methods.microsoft.snapshot.website=Official Website
account.methods.offline=Offline
account.methods.offline.name.special_characters=Using only English letters, numbers, and underscores is recommended
account.methods.offline.name.special_characters=Use only letters, numbers, and underscores (max 16 chars)
account.methods.offline.name.invalid=It is recommended to use only English letters, numbers and underscores for the username, and the length should not exceed 16 characters.\n\
\n\
\ · Legitimate: HuangYu, huang_Yu, Huang_Yu_123;\n\
@@ -183,6 +183,7 @@ button.export=Export
button.no=No
button.ok=OK
button.ok.countdown=OK (%d)
button.reveal_dir=Reveal
button.refresh=Refresh
button.remove=Remove
button.remove.confirm=Are you sure you want to permanently remove it? This action cannot be undone!
@@ -387,6 +388,9 @@ fatal.config_loading_failure=Cannot load configuration files.\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.config_unsupported_version=The current configuration file was created by a newer version of Hello Minecraft! Launcher, and this version of HMCL cannot load it properly.\n\
Please update and restart HMCL.\n\
Before updating the launcher, any settings you modify will not be saved.
fatal.mac_app_translocation=Hello Minecraft! Launcher is isolated to a temporary directory by the OS due to macOS security mechanisms.\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?
@@ -398,12 +402,12 @@ 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.deprecated_java_version=HMCL will require Java 11 or later to run in the future, but will still support launching games with Java 8.\n\
fatal.deprecated_java_version=HMCL will require Java 17 or later to run in the future, but will still support launching games with Java 6~16.\n\
\n\
It is recommended to install the latest version of Java to ensure that HMCL works properly.\n\
\n\
You can continue to keep the old version of Java. HMCL can recognize and manage multiple Java versions and will automatically select the appropriate Java for you based on the game version.
fatal.deprecated_java_version.update=HMCL will require Java 11 or later to run in the future. Please install the latest version of Java to ensure that HMCL can complete the upgrade.\n\
fatal.deprecated_java_version.update=HMCL will require Java 17 or later to run in the future. Please install the latest version of Java to ensure that HMCL can complete the upgrade.\n\
\n\
You can continue to keep the old version of Java.\
HMCL can recognize and manage multiple Java versions and will automatically select the appropriate Java for you based on the game version.
@@ -452,7 +456,7 @@ game.crash.reason.analyzing=Analyzing...
game.crash.reason.multiple=Several reasons detected:\n\n
game.crash.reason.block=The game crashed because of a block in the world.\n\
\n\
You can try removing this block using MCEdit or deleting the mod that added it.\n\
You can try removing this block using the <a href="https://minecraft.wiki/w/Tutorial:Programs_and_editors/Mapping#Map_editors">map editors</a> or deleting the mod that added it.\n\
\n\
Block Type: %1$s\n\
Location: %2$s
@@ -468,7 +472,7 @@ game.crash.reason.duplicated_mod=The game cannot continue to run because of dupl
Each mod can only be installed once. Please delete the duplicate mod and try again.
game.crash.reason.entity=The game crashed because of an entity in the world.\n\
\n\
You can try removing the entity using MCEdit or deleting the mod that added it.\n\
You can try removing the entity using the <a href="https://minecraft.wiki/w/Tutorial:Programs_and_editors/Mapping#Map_editors">map editors</a> or deleting the mod that added it.\n\
\n\
Entity Type: %1$s\n\
Location: %2$s
@@ -495,7 +499,7 @@ game.crash.reason.java_version_is_too_high=The game crashed because the Java ver
Please use the previous major 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 because of an inappropriate Java VM version.\n\
game.crash.reason.need_jdk11=The game crashed because of an inappropriate Java version.\n\
\n\
You need to download and install Java 11, and set it in "Global/Instance-specific Settings → Java".
game.crash.reason.mod_name=The game crashed because of mod filename problems.\n\
@@ -565,7 +569,7 @@ game.crash.reason.optifine_causes_the_world_to_fail_to_load=The game may not con
game.crash.reason.jdk_9=The game crashed because the Java version is 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 because the current memory allocation exceeded the 32-bit Java VM limit.\n\
game.crash.reason.jvm_32bit=The game crashed because the current memory allocation exceeded the 32-bit JVM limit.\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 computer.\n\
\n\
@@ -646,7 +650,7 @@ game.crash.reason.opengl_not_supported=The game crashed because your graphics dr
Or, you can update your graphic driver to the latest version and then try again.\n\
\n\
If your computer has a dedicated graphics card, please make sure the game is indeed using it for rendering. If the problem persists, please consider getting a new graphics card or a new computer.
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.
game.crash.reason.openj9=The game is unable to run on an OpenJ9 JVM. Please switch to a Java that uses the Hotspot JVM in "Global/Instance-specific Settings → Java" and relaunch the game. If you do not have one, you can download one.
game.crash.reason.out_of_memory=The game crashed because the computer ran out of memory.\n\
\n\
Maybe 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\
@@ -660,7 +664,7 @@ game.crash.reason.stacktrace=The crash reason is unknown. You can view its detai
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 because you are using an outdated Java VM version.\n\
game.crash.reason.too_old_java=The game crashed because you are using an outdated Java version.\n\
\n\
You need to switch to a newer Java version (%1$s) 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.
@@ -769,10 +773,10 @@ 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 prevent you from launching the game or affect gaming 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.auto=The current Java version is not compatible with the instance.\n\nClick "Yes" to automatically choose the most compatible Java 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 previous 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 "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 "Do not check Java VM compatibility" in "Global/Instance-specific Settings → Advanced Settings".
launch.advice.corrected=We have resolved the Java problem. If you still want to use your choice of Java version, you can disable "Do not check JVM 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 "Do not check JVM 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.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.
@@ -790,7 +794,7 @@ launch.advice.vanilla_linux_java_8=Minecraft 1.12.2 or earlier only supports Jav
launch.advice.vanilla_x86.translation=Minecraft is not fully supported on your platform, so you may experience missing features 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.cannot_create_jvm=We are unable to create a JVM. It may be caused by incorrect JVM arguments. You can try resolving it by removing all arguments you added in "Global/Instance-specific Settings → Advanced Settings → JVM Options".
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 batch script. Please try exporting it as a PowerShell script.
launch.failed.decompressing_natives=Failed to extract native libraries.\n
@@ -861,6 +865,7 @@ message.info=Information
message.success=Operation successfully completed
message.unknown=Unknown
message.warning=Warning
message.question=Question
modpack=Modpacks
modpack.choose=Choose Modpack
@@ -869,7 +874,7 @@ modpack.choose.local.detail=You can drag the modpack file here.
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.detail=Remember to go back to this page and drop the modpack file here after the modpack is downloaded.
modpack.choose.repository.detail=You can choose the desired modpack on the next page.
modpack.choose.remote.tooltip=Please enter your modpack URL
modpack.completion=Downloading dependencies
modpack.desc=Describe your modpack, including an introduction and probably some changelog. Markdown and images from URL are currently supported.
@@ -940,17 +945,20 @@ modpack.wizard.step.initialization.server=Click here for more information on how
modrinth.category.adventure=Adventure
modrinth.category.atmosphere=Atmosphere
modrinth.category.audio=Audio
modrinth.category.babric=Babric
modrinth.category.blocks=Blocks
modrinth.category.bloom=Bloom
modrinth.category.bta-babric=BTA (Babric)
modrinth.category.bukkit=Bukkit
modrinth.category.bungeecord=BungeeCord
modrinth.category.canvas=Canvas
modrinth.category.cartoon=Cartoon
modrinth.category.challenging=Challenging
modrinth.category.colored-lighting=Colored Lighting
modrinth.category.core-shaders=Core Shaders
modrinth.category.combat=Combat
modrinth.category.core-shaders=Core Shaders
modrinth.category.cursed=Cursed
modrinth.category.datapack=Datapack
modrinth.category.decoration=Decoration
modrinth.category.economy=Economy
modrinth.category.entities=Entities
@@ -958,6 +966,7 @@ modrinth.category.environment=Environment
modrinth.category.equipment=Equipment
modrinth.category.fabric=Fabric
modrinth.category.fantasy=Fantasy
modrinth.category.folia=Folia
modrinth.category.foliage=Foliage
modrinth.category.fonts=Fonts
modrinth.category.food=Food
@@ -967,7 +976,9 @@ modrinth.category.gui=GUI
modrinth.category.high=High
modrinth.category.iris=Iris
modrinth.category.items=Items
modrinth.category.java-agent=Java Agent
modrinth.category.kitchen-sink=Kitchen-Sink
modrinth.category.legacy-fabric=Legacy Fabric
modrinth.category.library=Library
modrinth.category.lightweight=Lightweight
modrinth.category.liteloader=LiteLoader
@@ -985,8 +996,10 @@ modrinth.category.models=Models
modrinth.category.modloader=Modloader
modrinth.category.multiplayer=Multiplayer
modrinth.category.neoforge=NeoForge
modrinth.category.nilloader=NilLoader
modrinth.category.optifine=OptiFine
modrinth.category.optimization=Optimization
modrinth.category.ornithe=Ornithe
modrinth.category.paper=Paper
modrinth.category.path-tracing=Path Tracing
modrinth.category.pbr=PBR
@@ -1015,8 +1028,6 @@ modrinth.category.vanilla-like=Vanilla-like
modrinth.category.velocity=Velocity
modrinth.category.waterfall=Waterfall
modrinth.category.worldgen=Worldgen
modrinth.category.datapack=Datapack
modrinth.category.folia=Folia
modrinth.category.8x-=8x-
modrinth.category.16x=16x
modrinth.category.32x=32x
@@ -1036,7 +1047,7 @@ mods.category=Category
mods.channel.alpha=Alpha
mods.channel.beta=Beta
mods.channel.release=Release
mods.check_updates=Check for Updates
mods.check_updates=Update
mods.check_updates.current_version=Current Version
mods.check_updates.empty=All mods are up-to-date
mods.check_updates.failed_check=Failed to check for updates.
@@ -1136,6 +1147,7 @@ world.info.player.food_level=Hunger Level
world.info.player.game_type=Game Mode
world.info.player.game_type.adventure=Adventure
world.info.player.game_type.creative=Creative
world.info.player.game_type.hardcore=Hardcore
world.info.player.game_type.spectator=Spectator
world.info.player.game_type.survival=Survival
world.info.player.health=Health
@@ -1239,18 +1251,18 @@ settings.advanced.custom_commands.hint=The following environment variables are p
\ · $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_check_jvm_validity=Do not check JVM compatibility
settings.advanced.dont_patch_natives=Do not attempt to automatically replace native libraries
settings.advanced.environment_variables=Environment Variables
settings.advanced.game_dir.default=Default (".minecraft/")
settings.advanced.game_dir.independent=Isolated (".minecraft/versions/<instance name>/", except for assets and libraries)
settings.advanced.java_permanent_generation_space=PermGen Space
settings.advanced.java_permanent_generation_space.prompt=in MiB
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" 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.jvm=JVM Options
settings.advanced.jvm_args=JVM Arguments
settings.advanced.jvm_args.prompt=\ · If the arguments entered in "JVM Arguments" are the same as the default arguments, it will not be added.\n\
\ · Enter any GC arguments in "JVM Arguments", and the G1 argument of the default arguments will be disabled.\n\
\ · Enable "Do not add default JVM 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
settings.advanced.launcher_visibility.hide_and_reopen=Hide the launcher and show it when the game closes
@@ -1262,11 +1274,12 @@ settings.advanced.natives_directory=Native Library Path
settings.advanced.natives_directory.choose=Choose the location of the desired native library
settings.advanced.natives_directory.custom=Custom
settings.advanced.natives_directory.default=Default
settings.advanced.natives_directory.default.version_id=<Version ID>
settings.advanced.natives_directory.hint=This option is intended only for users of Apple silicon 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.
settings.advanced.no_jvm_args=Do not add default Java VM arguments
settings.advanced.no_jvm_args=Do not add default JVM arguments
settings.advanced.precall_command=Pre-launch Command
settings.advanced.precall_command.prompt=Commands to execute before the game launches
settings.advanced.process_priority=Process Priority
@@ -1412,6 +1425,8 @@ update.note=Beta and Nightly channels may have more features or fixes, but they
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.tooltip=Update
update.preview=Preview HMCL releases early
update.preview.tooltip=Enable this option to receive new versions of HMCL early for testing before their official release.
version=Games
version.name=Instance Name
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2026 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
@@ -21,7 +21,6 @@
about=Acerca de
about.copyright=Copyright
about.copyright.statement=Copyright © 2025 huangyuhui.
about.author=Autor
about.author.statement=bilibili @huanghongxun
about.claim=EULA
@@ -184,6 +183,7 @@ button.export=Exportar
button.no=No
button.ok=Aceptar
button.ok.countdown=Aceptar (%d)
button.reveal_dir=Carpeta
button.refresh=Refrescar
button.remove=Eliminar
button.remove.confirm=¿Estás seguro de que deseas eliminarlo de forma permanente? ¡Esta acción no se puede deshacer!
@@ -400,12 +400,12 @@ fatal.apply_update_failure=Lo sentimos, pero Hello Minecraft! Launcher no puede
fatal.apply_update_need_win7=Hello Minecraft! Launcher no puede actualizarse automáticamente en Windows XP/Vista.\n\
\n\
Puedes actualizar manualmente descargando una versión más reciente del launcher desde %s.
fatal.deprecated_java_version=HMCL requerirá Java 11 o posterior para funcionar en el futuro, pero seguirá siendo compatible con el lanzamiento de juegos con Java 8.\n\
fatal.deprecated_java_version=HMCL requerirá Java 17 o posterior para funcionar en el futuro, pero seguirá siendo compatible con el lanzamiento de juegos con Java 6~16.\n\
\n\
Se recomienda instalar la última versión de Java para garantizar el correcto funcionamiento de HMCL.\n\
\n\
Puedes conservar la versión antigua de Java. HMCL puede reconocer y gestionar varias versiones de Java y elegirá automáticamente la adecuada para usted en función de la versión del juego.
fatal.deprecated_java_version.update=HMCL requerirá Java 11 o posterior para funcionar en el futuro. Por favor, instalar la última versión de Java para asegurarse de que el lanzador puede completar la actualización.\n\
fatal.deprecated_java_version.update=HMCL requerirá Java 17 o posterior para funcionar en el futuro. Por favor, instalar la última versión de Java para asegurarse de que el lanzador puede completar la actualización.\n\
\n\
Puedes conservar la versión antigua de Java.\
HMCL puede reconocer y gestionar varias versiones de Java \
@@ -454,12 +454,6 @@ game.crash.info=Información de colgado
game.crash.reason=Motivo del colgado
game.crash.reason.analyzing=Analizando...
game.crash.reason.multiple=Se han detectado varias razones:\n\n
game.crash.reason.block=El juego se ha colgado debido a un bloqueo en el mundo.\n\
\n\
Puedes intentar eliminar este bloque usando MCEdit o borrando el mod que lo añadió.\n\
\n\
Tipo de bloque: %1$s\n\
Ubicación: %2$s
game.crash.reason.bootstrap_failed=El juego se ha colgado debido al mod «%1$s».\n\
\n\
Puedes intentar borrarlo o actualizarlo.
@@ -473,12 +467,6 @@ game.crash.reason.duplicated_mod=El juego no puede iniciarse debido a la existen
%2$s\n\
\n\
Cada mod sólo puede instalarse una vez, por favor, elimine el mod duplicado e inténtelo de nuevo.
game.crash.reason.entity=El juego se ha colgado debido a una entidad en el mundo.\n\
\n\
Puedes intentar eliminar la entidad usando MCEdit o borrando el mod que la añadió.\n\
\n\
Tipo de entidad: %1$s\n\
Ubicación: %2$s
game.crash.reason.fabric_version_0_12=La versión de Fabric Loader 0.12 o posterior es incompatible con los mods instalados actualmente. Necesitas bajarlo a la versión 0.11.7.
game.crash.reason.fabric_warnings=El cargador de Fabric Loader ha advertido:\n\
\n\
@@ -499,7 +487,7 @@ game.crash.reason.graphics_driver=El juego se ha colgado debido a un problema co
Si tu ordenador tiene una tarjeta gráfica discreta, tienes que comprobar si el juego utiliza gráficos integrados/núcleo. Si es así, inicie el launcher utilizando su tarjeta gráfica discreta. Si el problema persiste, probablemente debería considerar la posibilidad de adquirir una nueva tarjeta gráfica o un nuevo ordenador.\n\
\n\
Si utiliza su tarjeta gráfica integrada, tenga en cuenta que Minecraft 1.16.5 o anterior requiere <a href="https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html">Java 1.8.0_51 o más antiguo</a> para la serie de procesadores Intel(R) Core(TM) 3000 o anteriores.
game.crash.reason.macos_failed_to_find_service_port_for_display=El juego no puede continuar debido a un fallo al inicializar la ventana OpenGL en la plataforma Apple silicon.\n\
game.crash.reason.macos_failed_to_find_service_port_for_display=El juego no puede continuar debido a un fallo al inicializar la ventana OpenGL en la plataforma con chips de Apple.\n\
\n\
Para este problema, HMCL no tiene soluciones directas por el momento. Intente abrir cualquier navegador y ponerlo en pantalla completa, luego vuelva a HMCL, inicie el juego y <b>vuelva rápidamente a la página del navegador</b> antes de que aparezca la ventana del juego, espere a que aparezca la ventana del juego y luego vuelva a la ventana del juego.
game.crash.reason.illegal_access_error=El juego se ha colgado por culpa de algún(os) mod(s).\n\
@@ -514,7 +502,7 @@ game.crash.reason.jdk_9=El juego se ha colgado porque la versión de Java es dem
game.crash.reason.need_jdk11=El juego se ha colgado debido a una versión inadecuada de Java.\n\
\n\
Debes descargar e instalar Java 11 y configurarlo en «Config. Global/Específica de instancia → Java».
game.crash.reason.jvm_32bit=El juego se ha colgado porque la asignación de memoria actual excedía el límite de 32 bits JVM.\n\
game.crash.reason.jvm_32bit=El juego se ha colgado porque la asignación de memoria actual excedía el límite de 32 bits de la JVM.\n\
\n\
Si su sistema operativo es de 64 bits, instale y utilice una versión de Java de 64 bits. De lo contrario, es posible que tenga que volver a instalar un sistema operativo de 64 bits o adquirir un ordenador más moderno.\n\
\n\
@@ -647,7 +635,7 @@ game.crash.reason.stacktrace=El motivo del cuelgue es desconocido. Puedes ver lo
Hay algunas palabras clave que pueden contener algunos nombres de mods. Puedes buscarlas en Internet para averiguar el problema tú mismo.\n\
\n\
%s
game.crash.reason.too_old_java=El juego se ha colgado porque estás utilizando una versión de Java VM obsoleta.\n\
game.crash.reason.too_old_java=El juego se ha colgado porque estás utilizando una versión de Java obsoleta.\n\
\n\
Tienes que cambiar a una versión de Java más reciente (%1$s) en «Config. Global/Específica de instancia → Java» y, a continuación, volver a ejecutar el juego. Puede descargar Java desde <a href="https://learn.microsoft.com/java/openjdk/download">aquí</a>.
game.crash.reason.unknown=No somos capaces de averiguar por qué se ha colgado el juego. Por favor, refiérase a los registros del juego.
@@ -775,10 +763,10 @@ lang.default=Usar idioma del sistema
launch.advice=%s ¿Todavía quieres continuar?
launch.advice.multi=Se han detectado los siguientes problemas:\n\n%s\n\nEstos problemas pueden impedir que inicies el juego o afectar a la experiencia de juego.\n\n¿Todavía quieres continuar?
launch.advice.java.auto=La versión actual de la máquina virtual de Java no cumple los requisitos del juego.\n\nHaga clic en «Sí» para elegir automáticamente la versión de Java VM más compatible. O bien, puede navegar hasta «Config. Global/Específica de instancia → Java» para elegir uno usted mismo.
launch.advice.java.auto=La versión actual de Java no es compatible con la instancia.\n\nHaga clic en «Sí» para elegir automáticamente la versión de Java más compatible. O bien, puede navegar hasta «Config. Global/Específica de instancia → Java» para elegir uno usted mismo.
launch.advice.java.modded_java_7=Minecraft 1.7.2 y versiones anteriores requieren Java 7 o anterior.
launch.advice.corrected=Hemos solucionado el problema de la máquina virtual de Java. Si todavía quieres utilizar la versión de Java que elijas, puedes desactivar la opción «No comprobar la compatibilidad de la JVM» en «Config. Global/Específica de instancia → Configuración avanzada».
launch.advice.uncorrected=Si todavía quieres utilizar la versión de Java que elijas, puedes desactivar la opción «No comprobar la compatibilidad de la JVM» en «Config. Global/Específica de instancia → Configuración avanzada».
launch.advice.corrected=Hemos resuelto el problema de Java. Si aún desea utilizar la versión de Java que elija, puede desactivar «No comprobar la compatibilidad con JVM» en «Config. Global/Específica de instancia → Configuración avanzada».
launch.advice.uncorrected=Si aún desea utilizar la versión de Java que elija, puede desactivar «No comprobar la compatibilidad con JVM» en «Config. Global/Específica de instancia → Configuración avanzada».
launch.advice.different_platform=Se recomienda la versión de 64 bits de Java para tu dispositivo, pero has instalado una de 32 bits.
launch.advice.forge2760_liteloader=La versión 2760 o posterior de Forge no es compatible con LiteLoader, por favor considere actualizar Forge a la versión 2773 o posterior.
launch.advice.forge28_2_2_optifine=La versión 28.2.2 o posterior de Forge no es compatible con OptiFine. Considere la posibilidad de actualizar Forge a la versión 28.2.1 o anterior.
@@ -796,7 +784,7 @@ launch.advice.vanilla_linux_java_8=Minecraft 1.12.2 o inferior sólo admite Java
launch.advice.vanilla_x86.translation=Minecraft no proporciona actualmente soporte oficial para arquitecturas distintas de x86 y x86-64.\n\nPor 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.advice.unknown=El juego no puede iniciarse por las siguientes razones:
launch.failed=No se puede ejecutar
launch.failed.cannot_create_jvm=No podemos crear una máquina virtual Java. Puede deberse a un problema con los argumentos de ejecución proporcionados, puede intentar solucionarlo eliminando todos los argumentos que haya añadido en la configuración de la instancia.
launch.failed.cannot_create_jvm=No podemos crear una JVM. Puede deberse a un problema con los argumentos de ejecución proporcionados, puede intentar solucionarlo eliminando todos los argumentos que haya añadido en la configuración de la instancia.
launch.failed.creating_process=No podemos crear un nuevo proceso, por favor compruebe la ruta de Java.\n
launch.failed.command_too_long=La longitud del comando excede la longitud máxima de un script bat. Por favor, intente exportarlo como un script de PowerShell.
launch.failed.decompressing_natives=No se han podido descomprimir las bibliotecas nativas.\n
@@ -876,7 +864,7 @@ modpack.choose.remote=Descargar desde Internet
modpack.choose.remote.detail=Se requiere un enlace de descarga directa al archivo modpack remoto
modpack.choose.remote.tooltip=Por favor, introduzca la URL de su modpack
modpack.choose.repository=Descargar Modpack de CurseForge o Modrinth
modpack.choose.repository.detail=Recuerda volver a esta página y soltar aquí el archivo del modpack una vez descargado.
modpack.choose.repository.detail=Puedes elegir el modpack que desees en la página siguiente.
modpack.completion=Descargando dependencias
modpack.desc=Describa su modpack, incluyendo una introducción y probablemente algún registro de cambios. Actualmente se admiten Markdown e imágenes desde URL.
modpack.description=Descripción
@@ -946,17 +934,20 @@ modpack.wizard.step.initialization.server=Haga clic aquí para ver más tutorial
modrinth.category.adventure=Aventura
modrinth.category.atmosphere=Atmósfera
modrinth.category.audio=Audio
modrinth.category.babric=Babric
modrinth.category.blocks=Bloqueos
modrinth.category.bloom=Resplandor
modrinth.category.bta-babric=BTA (Babric)
modrinth.category.bukkit=Bukkit
modrinth.category.bungeecord=BungeeCord
modrinth.category.canvas=Canvas
modrinth.category.cartoon=Caricatura
modrinth.category.challenging=Desafío
modrinth.category.colored-lighting=Iluminación de color
modrinth.category.core-shaders=Sombreadores de núcleo
modrinth.category.combat=Combate
modrinth.category.core-shaders=Sombreadores de núcleo
modrinth.category.cursed=Maldición
modrinth.category.datapack=Paquete de datos
modrinth.category.decoration=Decoración
modrinth.category.economy=Economía
modrinth.category.entities=Entidades
@@ -964,6 +955,7 @@ modrinth.category.environment=Medio ambiente
modrinth.category.equipment=Equipo
modrinth.category.fabric=Fabric
modrinth.category.fantasy=Fantasía
modrinth.category.folia=Folia
modrinth.category.foliage=Vegetación
modrinth.category.fonts=Fonts
modrinth.category.food=Alimentos
@@ -973,7 +965,9 @@ modrinth.category.gui=GUI
modrinth.category.high=Alto
modrinth.category.iris=Iris
modrinth.category.items=Objetos
modrinth.category.java-agent=Java Agent
modrinth.category.kitchen-sink=Fregadero de cocina
modrinth.category.legacy-fabric=Legacy Fabric
modrinth.category.library=Biblioteca
modrinth.category.lightweight=Peso ligero
modrinth.category.liteloader=LiteLoader
@@ -991,8 +985,10 @@ modrinth.category.models=Modelos
modrinth.category.modloader=Cargador de mods
modrinth.category.multiplayer=Multijugador
modrinth.category.neoforge=NeoForge
modrinth.category.nilloader=NilLoader
modrinth.category.optifine=OptiFine
modrinth.category.optimization=Optimización
modrinth.category.ornithe=Ornithe
modrinth.category.paper=Paper
modrinth.category.path-tracing=Trazado de rutas
modrinth.category.pbr=PBR
@@ -1021,8 +1017,6 @@ modrinth.category.vanilla-like=Similar a la vainilla
modrinth.category.velocity=Velocity
modrinth.category.waterfall=Waterfall
modrinth.category.worldgen=Generación de mundos
modrinth.category.datapack=Paquete de datos
modrinth.category.folia=Folia
modrinth.category.8x-=8x-
modrinth.category.16x=16x
modrinth.category.32x=32x
@@ -1042,7 +1036,7 @@ mods.category=Categoría
mods.channel.alpha=Alpha
mods.channel.beta=Beta
mods.channel.release=Release
mods.check_updates=Comprobar actualizaciones
mods.check_updates=Actualizar
mods.check_updates.current_version=Versión actual
mods.check_updates.empty=Todos los mods están actualizados
mods.check_updates.failed_check=No se ha podido comprobar si hay actualizaciones.
@@ -1245,18 +1239,18 @@ settings.advanced.custom_commands.hint=Se proporcionan las siguientes variables
\ · $INST_FABRIC: disponible si Fabric está instalado.\n\
\ · $INST_QUILT: disponible si Quilt está instalado.
settings.advanced.dont_check_game_completeness=No chequear integridad del juego
settings.advanced.dont_check_jvm_validity=No comprobar la compatibilidad de la JVM
settings.advanced.dont_check_jvm_validity=No comprobar la compatibilidad con JVM
settings.advanced.dont_patch_natives=No intente sustituir automáticamente las bibliotecas nativas
settings.advanced.environment_variables=Variables de entorno
settings.advanced.game_dir.default=Por defecto («.minecraft/»)
settings.advanced.game_dir.independent=Aislar («.minecraft/versions/<nombre de la instancia>/», excepto para los activos y las bibliotecas)
settings.advanced.java_permanent_generation_space=Espacio PermGen
settings.advanced.java_permanent_generation_space.prompt=en MiB
settings.advanced.jvm=Opciones de la máquina virtual de Java
settings.advanced.jvm_args=Argumentos de la máquina virtual de Java
settings.advanced.jvm_args.prompt=\ · Si los argumentos introducidos en «Argumentos de la máquina virtual de Java» son los mismos que los argumentos por defecto, no se añadirán.\n\
\ · Introduzca cualquier argumento GC en «Argumentos de la máquina virtual de Java», y se desactivará el argumento G1 de los argumentos por defecto.\n\
\ · Activa «No añadir argumentos por defecto de JVM» para ejecutar el juego sin añadir argumentos por defecto.
settings.advanced.jvm=Opciones de JVM
settings.advanced.jvm_args=Argumentos JVM
settings.advanced.jvm_args.prompt=\ · Si los argumentos introducidos en «Argumentos JVM» son los mismos que los argumentos por defecto, no se añadirán.\n\
\ · Introduzca cualquier argumento GC en «Argumentos JVM», y se desactivará el argumento G1 de los argumentos por defecto.\n\
\ · Activa «No añadir argumentos JVM por defecto» para ejecutar el juego sin añadir argumentos por defecto.
settings.advanced.launcher_visibility.close=Cerrar el launcher después de ejecutar el juego.
settings.advanced.launcher_visibility.hide=Ocultar el launcher después de ejecutar el juego.
settings.advanced.launcher_visibility.hide_and_reopen=Ocultar el launcher y volver a abrirlo cuando se cierra el juego.
@@ -1268,10 +1262,10 @@ settings.advanced.natives_directory=Ruta de la biblioteca nativa
settings.advanced.natives_directory.choose=Elija la ubicación de la biblioteca nativa deseada
settings.advanced.natives_directory.custom=Personalizado
settings.advanced.natives_directory.default=Por defecto
settings.advanced.natives_directory.hint=Esta opción está pensada sólo para usuarios de Apple M1 u otras plataformas no soportadas oficialmente. Por favor, no modifique esta opción a menos que sepa lo que está haciendo.\n\
settings.advanced.natives_directory.hint=Esta opción está pensada sólo para usuarios de chips de Apple u otras plataformas no soportadas oficialmente. Por favor, no modifique esta opción a menos que sepa lo que está haciendo.\n\
\n\
Antes de proceder, por favor, asegúrese de que todas las bibliotecas (por ejemplo, lwjgl.dll, libopenal.so) se proporcionan en su directorio deseado.
settings.advanced.no_jvm_args=No añadir argumentos por defecto de JVM
settings.advanced.no_jvm_args=No añadir argumentos JVM por defecto
settings.advanced.precall_command=Comando pre-lanzamiento:
settings.advanced.precall_command.prompt=El comando se ejecuta antes de que los juegos se lance
settings.advanced.process_priority=Prioridad del proceso
@@ -1413,6 +1407,8 @@ update.note=Advertencia: Las versiones beta y las versiones nocturnas pueden ten
update.latest=Esta es la última versión.
update.no_browser=No se puede abrir en el navegador del sistema. Pero, hemos copiado el enlace a su portapapeles y puede abrirlo manualmente.
update.tooltip=Actualización
update.preview=Vista previa de actualizaciones anticipadas
update.preview.tooltip=Activa esta opción para recibir nuevas versiones del lanzador antes de su lanzamiento oficial para probarlas
version=Juegos
version.name=Nombre de instancia
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2026 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
@@ -20,7 +20,6 @@
about=について
about.copyright=著作権
about.copyright.statement=Copyright © 2025 huangyuhui
about.author=著者
about.author.statement=bilibili @huanghongxun
about.claim=EULA
@@ -352,13 +351,11 @@ game.crash.info=ゲームステータス
game.crash.reason=クラッシュアナライザー
game.crash.reason.analyzing=分析中..
game.crash.reason.multiple=複数の理由が検出されました:\n\n
game.crash.reason.block=ブロックが原因でゲームを実行できません。\nMCEditでこのブロックを削除するか、関連するModを直接削除できます。\nブロックタイプ:%1$s\nブロックの場所:%2$s
game.crash.reason.bootstrap_failed=mod %1$s がクラッシュしたため、ゲームを実行できません。\n削除または更新を試みることができます。
game.crash.reason.config=modが構成ファイルを解析できないため、ゲームを実行できません。\nMod %1$s は構成ファイル %2$s を解析できません。
game.crash.reason.debug_crash=クラッシュが手動でトリガーされるため、ゲームを実行できません。\n実際、ゲームは無実であり、すべてあなたの責任です。
game.crash.reason.duplicated_mod=Mod %1$s が重複してインストールされているため、現在のゲームを継続して実行できません。\n%2$s\n各Modは1つしかインストールできませんので、余分なModを削除して再度お試しください。
game.crash.reason.mixin_apply_mod_failed=Mixin が %1$s モジュールを適用できないため、現在のゲームを続行できません。\n問題を解決するために、このモジュールを削除または更新してみてください。
game.crash.reason.entity=エンティティが原因でゲームを実行できません。\nMCEditでこのエンティティを削除するか、関連するModを直接削除できます。\nエンティティタイプ:%1$s\nエンティティの場所:%2$s
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 のログを確認できます。
@@ -791,7 +788,7 @@ settings.advanced.natives_directory=ネイティブライブラリパス(例
settings.advanced.natives_directory.choose=ネイティブライブラリパスを選択してください
settings.advanced.natives_directory.custom=Custom(ゲームが実行時に必要とするネイティブライブラリを提供する必要があります)
settings.advanced.natives_directory.default=Standard(ネイティブライブラリは当社が提供します)
settings.advanced.natives_directory.hint=このオプションは、AppleM1またはその他の公式にサポートされていないプラットフォーム/アーキテクチャでゲームをプレイする場合にのみ使用されます。\nこのオプションを変更する意味がわからない場合は、このオプションを変更しないことをお勧めします。、またはゲームが起動しません。\nこのオプションを変更する必要がある場合は、ゲームを実行するために必要なすべてのネイティブライブラリをカスタムネイティブディレクトリの下に配置する必要があります。lwjgl.dll(liblwjgl.so)、openal.dll(libopenal.so)。HMCLは、不足しているネイティブライブラリを提供しません。
settings.advanced.natives_directory.hint=このオプションは、Appleシリコンまたはその他の公式にサポートされていないプラットフォーム/アーキテクチャでゲームをプレイする場合にのみ使用されます。\nこのオプションを変更する意味がわからない場合は、このオプションを変更しないことをお勧めします。、またはゲームが起動しません。\nこのオプションを変更する必要がある場合は、ゲームを実行するために必要なすべてのネイティブライブラリをカスタムネイティブディレクトリの下に配置する必要があります。lwjgl.dll(liblwjgl.so)、openal.dll(libopenal.so)。HMCLは、不足しているネイティブライブラリを提供しません。
settings.advanced.no_jvm_args=デフォルトのJVM引数なし
settings.advanced.precall_command=起動前コマンド
settings.advanced.precall_command.prompt=ゲーム開始前に実行されます
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2026 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
@@ -20,7 +20,6 @@
about=О лаунчере
about.copyright=Авторские права
about.copyright.statement=Авторские права © 2025 huangyuhui.
about.author=Автор
about.author.statement=bilibili @huanghongxun
about.claim=EULA
@@ -398,12 +397,12 @@ fatal.apply_update_failure=Мы сожалеем, лаунчер не смог
Вы можете обновить программу вручную, скачав более новую версию с %s.
fatal.apply_update_need_win7=Лаунчер не может автоматически обновляться на Windows XP/Vista.\n\
Вы можете обновить программу вручную, скачав более новую версию с %s.
fatal.deprecated_java_version=В будущем для работы HMCL потребуется Java 11 или более поздняя версия, однако запуск игр будет поддерживаться и на Java 8.\n\
fatal.deprecated_java_version=В будущем для работы HMCL потребуется Java 17 или более поздняя версия, однако запуск игр будет поддерживаться и на Java 6~16.\n\
\n\
Рекомендуется установить последнюю версию Java, чтобы обеспечить правильную работу HMCL.\n\
\n\
Вы можете продолжать использовать старую версию Java. HMCL может распознавать и управлять несколькими версиями Java и автоматически выбирать подходящую Java в зависимости от версии игры.
fatal.deprecated_java_version.update=В будущем для работы HMCL потребуется Java 11 или более поздняя версия. Пожалуйста, установить последнюю версию Java, чтобы убедиться, что приложение сможет завершить обновление.\n\
fatal.deprecated_java_version.update=В будущем для работы HMCL потребуется Java 17 или более поздняя версия. Пожалуйста, установить последнюю версию Java, чтобы убедиться, что приложение сможет завершить обновление.\n\
\n\
Вы можете продолжать использовать старую версию Java.\
HMCL может распознавать и управлять несколькими версиями Java \
@@ -452,12 +451,6 @@ game.crash.info=Сведения об отказе
game.crash.reason=Анализатор сбоев
game.crash.reason.analyzing=Анализирование...
game.crash.reason.multiple=Обнаружено несколько причин:\n\n
game.crash.reason.block=Игра отказала из-за блока в мире.\n\
\n\
Удалите этот блок с помощью MCEdit или удалите мод связанный с ним напрямую.\n\
\n\
Тип блока: %1$s\n\
Расположение блока: %2$s
game.crash.reason.bootstrap_failed=Игра отказала из-за мода «%1$s».\n\
\n\
Попробуйте удалить или обновить его.
@@ -468,12 +461,6 @@ game.crash.reason.duplicated_mod=Не удалось продолжить зап
%2$s\n\
\n\
Каждый мод должен быть установлен только один, удалите дублирующий мод и попробуйте снова.
game.crash.reason.entity=Игра отказала из-за сущность в мире.\n\
\n\
Удалите эту сущность с помощью MCEdit или удалите мод связанный с ним напрямую.\n\
\n\
Тип сущность: %1$s\n\
Расположение сущность: %2$s
game.crash.reason.fabric_version_0_12=Fabric 0.12 (и выше) несовместим с установленными модами. Следует понизить версию fabric до 0.11.7.
game.crash.reason.mixin_apply_mod_failed=Игра отказала из-за невозможности применить mixin к моду «%1$s».\n\
\n\
@@ -875,7 +862,7 @@ modpack.choose.remote=Скачать
modpack.choose.remote.detail=Необходима прямая ссылка на скачивание модпака
modpack.choose.remote.tooltip=Введите URL-адрес модпака
modpack.choose.repository=Скачать модпак с CurseForge или Modrinth
modpack.choose.repository.detail=Не забудьте вернуться на эту страницу и перетащить файл модпака сюда после того, как модпак будет скачан.
modpack.choose.repository.detail=Вы сможете выбрать нужный вам модпак на следующей странице.
modpack.completion=Скачивание зависимостей
modpack.desc=Опишите модпак, включая введение и журнал изменений. Поддерживаются Markdown и изображения по URL-адресу.
modpack.description=Описание
@@ -945,17 +932,20 @@ modpack.wizard.step.initialization.server=Нажмите здесь для по
modrinth.category.adventure=Приключение
modrinth.category.atmosphere=Атмосфера
modrinth.category.audio=Аудио
modrinth.category.babric=Babric
modrinth.category.blocks=Блоки
modrinth.category.bloom=Свечение
modrinth.category.bta-babric=BTA (Babric)
modrinth.category.bukkit=Bukkit
modrinth.category.bungeecord=BungeeCord
modrinth.category.canvas=Canvas
modrinth.category.cartoon=Мультяшный
modrinth.category.challenging=Вызов
modrinth.category.colored-lighting=Цветное освещение
modrinth.category.core-shaders=Ядро шейдеров
modrinth.category.combat=Бой
modrinth.category.core-shaders=Ядро шейдеров
modrinth.category.cursed=Cursed
modrinth.category.datapack=Набор данных
modrinth.category.decoration=Украшения
modrinth.category.economy=Экономика
modrinth.category.entities=Сущности
@@ -963,6 +953,7 @@ modrinth.category.environment=Окружающая среда
modrinth.category.equipment=Оборудование
modrinth.category.fabric=Fabric
modrinth.category.fantasy=Фэнтези
modrinth.category.folia=Folia
modrinth.category.foliage=Растительность
modrinth.category.fonts=Шрифты
modrinth.category.food=Еда
@@ -972,7 +963,9 @@ modrinth.category.gui=ГИП
modrinth.category.high=Высокий
modrinth.category.iris=Iris
modrinth.category.items=Предметы
modrinth.category.java-agent=Java Agent
modrinth.category.kitchen-sink=Kitchen-Sink
modrinth.category.legacy-fabric=Legacy Fabric
modrinth.category.library=Библиотека
modrinth.category.lightweight=Легкий
modrinth.category.liteloader=LiteLoader
@@ -990,8 +983,10 @@ modrinth.category.models=Модели
modrinth.category.modloader=Мод-загрузчик
modrinth.category.multiplayer=Сетевая игра
modrinth.category.neoforge=NeoForge
modrinth.category.nilloader=NilLoader
modrinth.category.optifine=OptiFine
modrinth.category.optimization=Оптимизация
modrinth.category.ornithe=Ornithe
modrinth.category.paper=Paper
modrinth.category.path-tracing=Трассировка пути
modrinth.category.pbr=PBR
@@ -1020,8 +1015,6 @@ modrinth.category.vanilla-like=Ванильное
modrinth.category.velocity=Velocity
modrinth.category.waterfall=Waterfall
modrinth.category.worldgen=Генерация мира
modrinth.category.datapack=Набор данных
modrinth.category.folia=Folia
modrinth.category.8x-=8x-
modrinth.category.16x=16x
modrinth.category.32x=32x
@@ -1244,18 +1237,18 @@ settings.advanced.custom_commands.hint=Пользовательские кома
\ · $INST_FABRIC: устанавливается, если установлен Fabric.\n\
\ · $INST_QUILT: устанавливается, если установлен Quilt.
settings.advanced.dont_check_game_completeness=Не проверять целостность игры
settings.advanced.dont_check_jvm_validity=Не проверять совместимость Java VM
settings.advanced.dont_check_jvm_validity=Не проверять совместимость JVM
settings.advanced.dont_patch_natives=Не пытайтесь автоматически заменить нативные библиотеки
settings.advanced.environment_variables=Переменные среды
settings.advanced.game_dir.default=По умолчанию («.minecraft/»)
settings.advanced.game_dir.independent=Раздельно («.minecraft/versions/<имя сборки>/», кроме assets и библиотек)
settings.advanced.java_permanent_generation_space=Пространство PermGen
settings.advanced.java_permanent_generation_space.prompt=в МиБ
settings.advanced.jvm=Настройки Java VM
settings.advanced.jvm_args=Аргументы Java VM
settings.advanced.jvm_args.prompt=\ · Если параметр, введённый в «Аргументы Java VM», совпадает с параметром по умолчанию, он не будет добавлен.\n\
\ · Введите любые параметры GC в «Аргументы Java VM», параметр G1 по умолчанию будет отключен.\n\
\ · Нажмите «Не добавлять аргументы Java VM по умолчанию» ниже, чтобы запустить игру без добавления аргументов по умолчанию.
settings.advanced.jvm=Настройки JVM
settings.advanced.jvm_args=Аргументы JVM
settings.advanced.jvm_args.prompt=\ · Если параметр, введённый в «Аргументы JVM», совпадает с параметром по умолчанию, он не будет добавлен.\n\
\ · Введите любые параметры GC в «Аргументы JVM», параметр G1 по умолчанию будет отключен.\n\
\ · Нажмите «Не добавлять аргументы JVM по умолчанию» ниже, чтобы запустить игру без добавления аргументов по умолчанию.
settings.advanced.launcher_visibility.close=Закрывать после запуска игры
settings.advanced.launcher_visibility.hide=Скрыть после запуска игры
settings.advanced.launcher_visibility.hide_and_reopen=Скрыть после запуска и показать после закрытия игры
@@ -1271,7 +1264,7 @@ settings.advanced.natives_directory.hint=Параметр предназначе
\n\
Прежде чем продолжить, убедитесь что все библиотеки (например, lwjgl.dll, libopenal.so) находятся в нужной папке.\n\
Примечание: Рекомендуется использовать полностью английские пути для указанных файлов локальных библиотек, иначе игра может не запуститься.
settings.advanced.no_jvm_args=Не добавлять аргументы Java VM по умолчанию
settings.advanced.no_jvm_args=Не добавлять аргументы JVM по умолчанию
settings.advanced.precall_command=Команда перед запуском
settings.advanced.precall_command.prompt=Команды, которые необходимо выполнить перед запуском игры
settings.advanced.process_priority=Приоритет процесса
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2026 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
@@ -20,7 +20,7 @@
about=關於
about.copyright=著作權
about.copyright.statement=著作權所有 © 2025 huangyuhui
about.copyright.statement=著作權所有 © 2013-2026 huangyuhui 與貢獻者
about.author=作者
about.author.statement=bilibili @huanghongxun
about.claim=使用者協議
@@ -97,7 +97,7 @@ account.register=註冊
account.manage=帳戶清單
account.copy_uuid=複製該帳戶的 UUID
account.methods=登入方式
account.methods.authlib_injector=外置登入
account.methods.authlib_injector=外部登入
account.methods.microsoft=Microsoft 帳戶
account.methods.microsoft.birth=如何變更帳戶出生日期
account.methods.microsoft.deauthorize=移除應用存取權
@@ -131,7 +131,7 @@ account.methods.ban_query=查詢帳戶是否被封禁
account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL。請下載官方版本進行登入。
account.methods.microsoft.snapshot.website=官方網站
account.methods.offline=離線模式
account.methods.offline.name.special_characters=建議使用英文字母、數字以及底線命名
account.methods.offline.name.special_characters=建議使用英文字母、數字以及底線命名,且長度不超過 16 個字元
account.methods.offline.name.invalid=遊戲使用者名稱建議僅使用英文字母、數字及底線,且長度不超過 16 個字元。\n\
\n\
\ · 一些有效的使用者名稱:HuangYu、huang_Yu、Huang_Yu_123;\n\
@@ -186,6 +186,7 @@ button.export=匯出
button.no=否
button.ok=確定
button.ok.countdown=確定 (%d)
button.reveal_dir=開啟目錄
button.refresh=重新整理
button.remove=刪除
button.remove.confirm=你確認要刪除嗎?該操作無法復原!
@@ -360,7 +361,7 @@ exception.access_denied=無法存取檔案「%s」。因為 HMCL 沒有對該檔
請你檢查目前作業系統帳戶是否能訪存取檔案,比如非管理員使用者可能不能訪問其他帳戶的個人目錄內的檔案。\n\
對於 Windows 使用者,你還可以嘗試透過資源監視器查看是否有程式占用了該檔案。如果是,你可以關閉占用此檔案的程式,或者重啟電腦再試。
exception.artifact_malformed=下載的檔案正確,但無法透過校驗。
exception.ssl_handshake=無法建立 SSL 連線。因為目前 Java 虛擬機缺少相關的 SSL 證書。你可以嘗試使用其他的 Java 虛擬機或關閉網路代理開啟 HMCL 再試。
exception.ssl_handshake=無法建立 SSL 連線。目前 Java 缺少相關的 SSL 證書。你可以嘗試使用其他 Java 或關閉網路代理開啟 HMCL 再試。
extension.bat=Windows 批次檔
extension.mod=模組檔案
@@ -376,12 +377,13 @@ fatal.config_change_owner_root=你正在使用 root 帳戶開啟 Hello Minecraft
fatal.config_in_temp_dir=你正在暫存目錄中開啟 Hello Minecraft! Launcher,你的設定和遊戲資料可能會遺失。建議將 HMCL 移動至其他位置再開啟。\n是否繼續開啟?
fatal.config_loading_failure=Hello Minecraft! Launcher 無法載入設定檔案。\n請確保 HMCL 對「%s」目錄及該目錄下的檔案擁有讀寫權限。
fatal.config_loading_failure.unix=Hello Minecraft! Launcher 無法載入設定檔案,因為設定檔案是由使用者「%1$s」建立的。\n請使用 root 帳戶開啟 HMCL (不推薦),或在終端中執行以下指令將設定檔案的所有權變更為目前使用者:\n%2$s
fatal.config_unsupported_version=當前設定檔案是由更高版本的 Hello Minecraft! Launcher 建立的,目前版本的 HMCL 無法正常載入。請更新並重新啟動 HMCL。\n在更新啟動器之前,你所做的所有設定更改都不會被保存。
fatal.mac_app_translocation=由於 macOS 的安全機制,Hello Minecraft! Launcher 被系統隔離至暫存目錄中。\n請將 HMCL 移動到其他目錄後再嘗試開啟,否則你的設定和遊戲資料可能會在重啟後遺失。\n是否繼續開啟?
fatal.migration_requires_manual_reboot=Hello Minecraft! Launcher 即將升級完成,請重新開啟 HMCL。
fatal.apply_update_failure=我們很抱歉 Hello Minecraft! Launcher 無法自動完成升級程式,因為出現了一些問題。\n但你依然可以從 %s 處手動下載 HMCL 來完成升級。
fatal.apply_update_need_win7=Hello Minecraft! Launcher 無法在 Windows XP/Vista 上進行自動更新。請從 %s 處手動下載 HMCL 來完成升級。
fatal.deprecated_java_version=HMCL 未來需要 Java 11 或更高版本才能執行,但依然支援使用 Java 8 啟動遊戲。建議安裝最新版本的 Java 以確保 HMCL 正常執行。\n你可以繼續保留舊版本 Java。HMCL 能夠識別與管理多個 Java,並會自動根據遊戲版本為你選取合適的 Java。
fatal.deprecated_java_version.update=更高版本的 HMCL 需要 Java 11 或更高版本才能執行,請安裝最新版本的 Java 以確保 HMCL 能夠完成升級。\n你可以繼續保留舊版本 Java。HMCL 能夠識別與管理多個 Java,並會自動根據遊戲版本為你選取合適的 Java。
fatal.deprecated_java_version=HMCL 未來需要 Java 17 或更高版本才能執行,但依然支援使用 Java 6~16 啟動遊戲。建議安裝最新版本的 Java 以確保 HMCL 正常執行。\n你可以繼續保留舊版本 Java。HMCL 能夠識別與管理多個 Java,並會自動根據遊戲版本為你選取合適的 Java。
fatal.deprecated_java_version.update=更高版本的 HMCL 需要 Java 17 或更高版本才能執行,請安裝最新版本的 Java 以確保 HMCL 能夠完成升級。\n你可以繼續保留舊版本 Java。HMCL 能夠識別與管理多個 Java,並會自動根據遊戲版本為你選取合適的 Java。
fatal.deprecated_java_version.download_link=下載 Java %d
fatal.samba=如果您正在透過 Samba 共亯的目錄中開啟 Hello Minecraft! Launcher,啟動器可能無法正常工作,請嘗試更新您的 Java 或在本機目錄內開啟 HMCL。
fatal.illegal_char=由於您的使用者目錄路徑中存在無效字元『=』,您將無法使用外部登入帳戶以及離線登入更換外觀功能。
@@ -418,26 +420,26 @@ game.crash.info=遊戲訊息
game.crash.reason=崩潰原因
game.crash.reason.analyzing=分析中……
game.crash.reason.multiple=檢測到多個原因:\n\n
game.crash.reason.block=目前遊戲由於某個方塊不能正常工作,無法繼續執行。\n你可以嘗試使用 MCEdit 工具編輯存檔刪除該方塊,或者直接刪除對應的模組。\n方塊類型:%1$s\n方塊坐標:%2$s
game.crash.reason.block=目前遊戲由於某個方塊不能正常工作,無法繼續執行。\n你可以嘗試使用地圖編輯工具編輯存檔刪除該方塊,或者直接刪除對應的模組。\n方塊類型:%1$s\n方塊坐標:%2$s\n\n相關工具:<a href="https://minecraft.wiki/w/Tutorial:Programs_and_editors/Mapping#Map_editors">英文 Wiki</a> | <a href="https://zh.minecraft.wiki/w/辅助程序与编辑器/地图工具?variant=zh-tw#地图编辑工具">中文 Wiki</a>
game.crash.reason.bootstrap_failed=目前遊戲由於模組「%1$s」出現問題,無法繼續執行。\n你可以嘗試刪除或更新該模組以解決問題。
game.crash.reason.mixin_apply_mod_failed=目前遊戲由於 Mixin 無法應用於「%1$s」模組,無法繼續執行。\n你可以嘗試刪除或更新該模組以解決問題。
game.crash.reason.config=目前遊戲由於無法解析模組配置檔案,無法繼續執行\n模組「%1$s」的配置檔案「%2$s」無法被解析。
game.crash.reason.debug_crash=目前遊戲由於手動觸發崩潰,無法繼續執行。\n事實上遊戲並沒有問題,問題都是你造成的!
game.crash.reason.duplicated_mod=目前遊戲由於模組重複安裝,無法繼續執行。\n%s\n每種模組只能安裝一個,請你刪除多餘的模組再試。
game.crash.reason.entity=目前遊戲由於某個實體不能正常工作,無法繼續執行。\n你可以嘗試使用 MCEdit 工具編輯存檔刪除該實體,或者直接刪除對應的模組。\n實體類型:%1$s\n實體坐標:%2$s
game.crash.reason.entity=目前遊戲由於某個實體不能正常工作,無法繼續執行。\n你可以嘗試使用地圖編輯工具編輯存檔刪除該實體,或者直接刪除對應的模組。\n實體類型:%1$s\n實體坐標:%2$s\n\n相關工具:<a href="https://minecraft.wiki/w/Tutorial:Programs_and_editors/Mapping#Map_editors">英文 Wiki</a> | <a href="https://zh.minecraft.wiki/w/辅助程序与编辑器/地图工具?variant=zh-tw#地图编辑工具">中文 Wiki</a>
game.crash.reason.fabric_version_0_12=Fabric Loader 0.12 及更高版本與目前已經安裝的模組可能不相容,你需要將 Fabric Loader 降級至 0.11.7。
game.crash.reason.fabric_warnings=Fabric 提供了一些警告訊息:\n%1$s
game.crash.reason.modmixin_failure=目前遊戲由於某些模組注入失敗,無法繼續執行。\n這一般代表著該模組存在問題,或與目前環境不相容。\n你可以查看日誌尋找出錯模組。
game.crash.reason.mod_repeat_installation=目前遊戲由於重複安裝了多個相同的模組,無法繼續執行。\n每個模組只能出現一次,請刪除重複的模組,然後再啟動遊戲。
game.crash.reason.forge_error=Forge/NeoForge 可能已經提供了錯誤資訊。\n你可以查看日誌,並根據錯誤報告中的日誌資訊進行對應處。\n如果沒有看到報錯資訊,可以查看錯誤報告了解錯誤具體是如何發生的。\n%1$s
game.crash.reason.mod_resolution0=目前遊戲由於一些模組出現問題,無法繼續執行。\n你可以查看日誌尋找出錯模組。
game.crash.reason.need_jdk11=目前遊戲由於 Java 虛擬機版本不合適,無法繼續執行。\n你需要下載安裝 Java 11,並在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中將 Java 設定為 11.x 的版本。
game.crash.reason.need_jdk11=目前遊戲由於 Java 版本不合適,無法繼續執行。\n你需要下載安裝 Java 11,並在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中將 Java 設定為 11.x 的版本。
game.crash.reason.java_version_is_too_high=目前遊戲由於使用的 Java 版本過高而崩潰了,無法繼續執行。\n請在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中改用較低版本的 Java,然後再啟動遊戲。\n如果沒有,可以從 <a href="https://www.java.com/download/">java.com (Java 8)</a> 或 <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java 17)</a> 等平台下載、安裝一個 (安裝完後需重啟啟動器)。
game.crash.reason.mod_name=目前遊戲由於模組檔案名稱問題,無法繼續執行。\n模組檔案名稱應只使用半型的大小寫字母 (Aa~Zz)、數位 (0~9)、橫線 (-)、底線 (_)和點 (.)。\n請到模組目錄中將所有不合規的模組檔案名稱修正為上述合規字元。
game.crash.reason.incomplete_forge_installation=目前遊戲由於 Forge 安裝不完整,無法繼續執行。\n請在「實例管理 - 自動安裝」中移除 Forge 並重新安裝。
game.crash.reason.file_already_exists=目前遊戲由於檔案「%1$s」已經存在,無法繼續執行。\n如果你認為這個檔案可以刪除,你可以在備份這個檔案後嘗試刪除它,並重新啟動遊戲。
game.crash.reason.file_changed=目前遊戲由於檔案校驗失敗,無法繼續執行。\n如果你手動修改了 Minecraft.jar 檔案,你需要回退修改,或者重新下載遊戲。
game.crash.reason.gl_operation_failure=目前遊戲由於你使用的某些模組/光影包/資源包/紋理包出現問題,無法繼續執行。\n請先嘗試禁用你所使用的模組/光影包/資源包/紋理包再試。
game.crash.reason.gl_operation_failure=目前遊戲由於你使用的某些模組/光影包/資源包/紋理包出現問題,無法繼續執行。\n請先嘗試停用你所使用的模組/光影包/資源包/紋理包再試。
game.crash.reason.graphics_driver=目前遊戲由於你的顯示卡驅動存在問題崩潰了。請嘗試升級你的顯示卡驅動到最新版本後再嘗試啟動遊戲。\n\
如果你的電腦同時存在獨立顯示卡與整合式顯示卡,你需要檢查遊戲是否使用整合式顯示卡啟動。如果是,請嘗試使用獨立顯示卡開啟 HMCL 與遊戲。如果仍有問題,你可能需要考慮換一個新顯示卡或新電腦。\n\
如果你確實需要使用整合式顯示卡,請檢查你電腦的 CPU 是否為 Intel(R) Core(TM) 3000 系列或更舊的處理器。如果是,對於 Minecraft 1.16.5 及更低版本,請你將遊戲所使用的 Java 版本降級至 1.8.0_51 及更低版本;否則你需要更換獨立顯示卡或新電腦。
@@ -445,7 +447,7 @@ game.crash.reason.macos_failed_to_find_service_port_for_display=目前遊戲由
game.crash.reason.illegal_access_error=目前遊戲由於某些模組的問題,無法繼續執行。\n如果你認識「%1$s」,你可以更新或刪除對應模組再試。
game.crash.reason.install_mixinbootstrap=目前遊戲由於缺失 MixinBootstrap,無法繼續執行。\n你可以嘗試安裝 <a href="https://www.curseforge.com/minecraft/mc-mods/mixinbootstrap">MixinBootstrap</a> 解決該問題。若安裝後崩潰,可以嘗試在該模組的檔案名前新增半形驚嘆號 (!) 解決。
game.crash.reason.jdk_9=目前遊戲由於 Java 版本過高,無法繼續執行。\n你需要下載安裝 Java 8,並在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中將 Java 設定為 1.8.x 的版本。
game.crash.reason.jvm_32bit=目前遊戲由於記憶體分配過大,超過了 32 位 Java 記憶體限制,無法繼續執行。\n如果你的電腦是 64 位系統,請下載安裝並更換 64 位 Java。\n如果你的電腦是 32 位系統,你或許可以重新安裝 64 位系統,或換一台新電腦。\n或者,你可以關閉「(全域/實例特定) 遊戲設定 → 遊戲記憶體」中的「自動分配」,並且把記憶體分配值調節為 1024 MiB 或以下。
game.crash.reason.jvm_32bit=目前遊戲由於記憶體分配過大,超過了 32 位 Java 虛擬機記憶體限制,無法繼續執行。\n如果你的電腦是 64 位系統,請下載安裝並更換 64 位 Java。\n如果你的電腦是 32 位系統,你或許可以重新安裝 64 位系統,或換一台新電腦。\n或者,你可以關閉「(全域/實例特定) 遊戲設定 → 遊戲記憶體」中的「自動分配」,並且把記憶體分配值調節為 1024 MiB 或以下。
game.crash.reason.loading_crashed_forge=目前遊戲由於模組「%1$s (%2$s)」錯誤,無法繼續執行。\n你可以嘗試刪除或更新該模組以解決問題。
game.crash.reason.loading_crashed_fabric=目前遊戲由於模組「%1$s」錯誤,無法繼續執行。\n你可以嘗試刪除或更新該模組以解決問題。
game.crash.reason.mac_jdk_8u261=目前遊戲由於你所使用的 Forge 或 OptiFine 與 Java 衝突而崩潰。\n請嘗試更新 Forge 和 OptiFine,或使用 Java 8u251 及更早版本啟動。
@@ -473,11 +475,11 @@ game.crash.reason.rtss_forest_sodium=目前遊戲由於 RivaTuner Statistics Ser
game.crash.reason.no_class_def_found_error=目前遊戲由於程式碼不完整,無法繼續執行。\n你的遊戲可能缺失了某個模組,或者某些模組檔案不完整,或者模組與遊戲的版本不匹配。\n你可能需要重新安裝遊戲和模組,或請求他人幫助。\n缺失:%1$s
game.crash.reason.no_such_method_error=目前遊戲由於程式碼不完整,無法繼續執行。\n你的遊戲可能缺失了某個模組,或者某些模組檔案不完整,或者模組與遊戲的版本不匹配。\n你可能需要重新安裝遊戲和模組,或請求他人幫助。
game.crash.reason.opengl_not_supported=目前遊戲由於你的顯示卡驅動存在問題,無法繼續執行。\n原因是 OpenGL 不受支援,你現在是否在遠端桌面或者串流模式下?如果是,請直接使用原電腦啟動遊戲。\n或者嘗試升級你的顯示卡驅動到最新版本後再嘗試啟動遊戲。如果你的電腦同時存在獨立顯示卡與整合式顯示卡,你需要檢查遊戲是否使用整合式顯示卡啟動。如果是,請嘗試使用獨立顯示卡開啟 HMCL 與遊戲。如果仍有問題,你可能需要考慮換一個新顯示卡或新電腦。
game.crash.reason.openj9=目前遊戲無法執行在 OpenJ9 虛擬機上。請你在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中更換 Hotspot Java 虛擬機,並重新啟動遊戲。如果沒有下載安裝,你可以在網路上自行下載。
game.crash.reason.openj9=目前遊戲無法執行在 OpenJ9 虛擬機上。請你在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中更換為使用 Hotspot 虛擬機的 Java,並重新啟動遊戲。如果沒有下載安裝,你可以在網路上自行下載。
game.crash.reason.out_of_memory=目前遊戲由於記憶體不足,無法繼續執行。\n這可能是記憶體分配過小,或者模組數量過多導致的。\n你可以在「(全域/實例特定) 遊戲設定 → 遊戲記憶體」中調整遊戲記憶體分配值以允許遊戲在更大的記憶體下執行。\n如果仍然出現該錯誤,你可能需要換一台更好的電腦。
game.crash.reason.resolution_too_high=目前遊戲由於資源包/紋理包解析度過高,無法繼續執行。\n你可以更換一個解析度更低的資源包/紋理包,或者更換一個視訊記憶體更大的顯示卡。
game.crash.reason.stacktrace=原因未知。請點擊日誌按鈕查看詳細訊息。\n下面是一些關鍵字,其中可能包含模組名稱,你可以透過搜尋的方式尋找有關訊息。\n%s
game.crash.reason.too_old_java=目前遊戲由於 Java 虛擬機版本過低,無法繼續執行。\n你需要在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中更換 %1$s 或更高版本的 Java 虛擬機,並重新啟動遊戲。如果沒有下載安裝,你可以點擊 <a href="https://learn.microsoft.com/java/openjdk/download">此處</a> 下載 Microsoft JDK。
game.crash.reason.too_old_java=目前遊戲由於 Java 版本過低,無法繼續執行。\n你需要在「(全域/實例特定) 遊戲設定 → 遊戲 Java」中更換 %1$s 或更高版本的 Java,並重新啟動遊戲。如果沒有下載安裝,你可以點擊 <a href="https://learn.microsoft.com/java/openjdk/download">此處</a> 下載 Microsoft JDK。
game.crash.reason.unknown=原因未知。請點擊日誌按鈕查看詳細訊息。
game.crash.reason.unsatisfied_link_error=目前遊戲由於缺少本機庫,無法繼續執行。\n這些本機庫缺失:%1$s。\n如果你在「(全域/實例特定) 遊戲設定 → 進階設定」中修改了本機庫路徑選項,請你修改回預設模式。\n如果你正在使用預設模式,請檢查遊戲目錄路徑是否只包含英文字母、數字和底線。\n如果是,那麼請檢查是否為模組或 HMCL 導致了本機庫缺失的問題。如果你確定是 HMCL 引起的,建議你向我們回報。\n<b>對於 Windows 使用者,你還可以嘗試在「控制台 → 時鐘和區域 → 地區 → 系統管理 → 變更系統區域設定」中,關閉「Beta:使用 Unicode UTF-8 提供全球語言支援」選項;</b>\n<b>或將遊戲目錄路徑中的所有非英文字母的名稱 (例如中文、空格等) 修改為英文字母。</b>\n如果你確實需要自訂本機庫路徑,你需要保證其中包含缺失的本機庫!
game.crash.title=遊戲意外退出
@@ -544,9 +546,9 @@ install.success=安裝成功
java.add=添加 Java
java.add.failed=Java 無效或與目前平臺不相容
java.disable=禁用此 Java
java.disable.confirm=你確定要禁用此 Java 嗎?
java.disabled.management=管理已禁用的 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
@@ -578,10 +580,10 @@ lang.default=使用系統語言
launch.advice=%s 是否繼續啟動?
launch.advice.multi=檢測到以下問題:\n\n%s\n\n這些問題可能導致遊戲無法正常啟動或影響遊戲體驗,是否繼續啟動?
launch.advice.java.auto=目前選取的 Java 虛擬機版本不滿足遊戲要求,是否自動選取合適的 Java 虛擬機版本?\n或者你可以到「(全域/實例特定) 遊戲設定 → 遊戲 Java」中選取一個合適的 Java 虛擬機版本。
launch.advice.java.auto=目前選取的 Java 版本不滿足遊戲要求,是否自動選取合適的 Java 版本?\n或者你可以到「(全域/實例特定) 遊戲設定 → 遊戲 Java」中選取一個合適的 Java 版本。
launch.advice.java.modded_java_7=Minecraft 1.7.2 及更低版本需要 Java 7 及更低版本。
launch.advice.corrected=我們已經修正了問題。如果你確實希望使用你自訂的 Java 虛擬機,你可以在「(全域/實例特定) 遊戲設定 → 進階設定」中往下滑,開啟「不檢查 JVM 與遊戲的相容性」。
launch.advice.uncorrected=如果你確實希望使用你自訂的 Java 虛擬機,你可以在「(全域/實例特定) 遊戲設定 → 進階設定」中往下滑,開啟「不檢查 JVM 與遊戲的相容性」。
launch.advice.corrected=我們已經修正了 Java 版本問題。如果你確實希望使用你自訂的 Java,你可以在「(全域/實例特定) 遊戲設定 → 進階設定」中往下滑,開啟「不檢查 Java 虛擬機與遊戲的相容性」。
launch.advice.uncorrected=如果你確實希望使用你自訂的 Java,你可以在「(全域/實例特定) 遊戲設定 → 進階設定」中往下滑,開啟「不檢查 Java 虛擬機與遊戲的相容性」。
launch.advice.different_platform=你正在使用 32 位元 Java 啟動遊戲。建議更換至 64 位元 Java。
launch.advice.forge2760_liteloader=Forge 14.23.5.2760 與 LiteLoader 不相容。請更新 Forge 至 14.23.5.2773 或更高版本。
launch.advice.forge28_2_2_optifine=Forge 28.2.2 及更高版本與 OptiFine 不相容,請降級 Forge 至 28.2.1 或更低版本。
@@ -599,7 +601,7 @@ launch.advice.vanilla_linux_java_8=對於 Linux x86-64 平台,Minecraft 1.12.2
launch.advice.vanilla_x86.translation=Minecraft 尚未為你的平臺提供完善支援,所以可能影響遊戲體驗或無法啟動遊戲。\n你可以在 <a href="https://learn.microsoft.com/java/openjdk/download">這裡</a> 下載 <b>x86-64</b> 架構的 Java 以獲得更完整的體驗。\n是否繼續啟動?
launch.advice.unknown=由於以下原因,無法繼續啟動遊戲:
launch.failed=啟動失敗
launch.failed.cannot_create_jvm=無法建立 Java 虛擬機,可能是 Java 參數有問題。可以在「(全域/實例特定) 遊戲設定 → 進階設定 → Java 虛擬機設定」中移除所有 Java 虛擬機參數後,嘗試再次啟動遊戲。
launch.failed.cannot_create_jvm=無法建立 Java 虛擬機。可能是虛擬機參數有問題。可以在「(全域/實例特定) 遊戲設定 → 進階設定 → Java 虛擬機設定」中移除所有虛擬機參數後,嘗試再次啟動遊戲。
launch.failed.creating_process=啟動失敗,在建立新處理程式時發生錯誤。可能是 Java 路徑錯誤。
launch.failed.command_too_long=指令長度超過限制,無法建立批次檔指令碼,請匯出為 PowerShell 指令碼。
launch.failed.decompressing_natives=無法解壓縮遊戲本機庫。
@@ -610,7 +612,7 @@ launch.failed.execution_policy.failed_to_set=設定執行策略失敗
launch.failed.execution_policy.hint=目前執行策略封鎖你執行 PowerShell 指令碼。\n點擊「確定」允許目前使用者執行本機 PowerShell 指令碼,或點擊「取消」保持現狀。
launch.failed.exited_abnormally=遊戲非正常退出。請查看日誌檔案,或聯絡他人尋求幫助。
launch.failed.java_version_too_low=你所指定的 Java 版本過低。請重新設定 Java 版本。
launch.failed.no_accepted_java=找不到適合目前遊戲使用的 Java。是否使用預設 Java 啟動遊戲?點擊「是」使用預設 Java 繼續啟動遊戲,\n或者請到「(全域/實例特定) 遊戲設定 → 遊戲 Java」中選取一個合適的 Java 虛擬機版本。
launch.failed.no_accepted_java=找不到適合目前遊戲使用的 Java。是否使用預設 Java 啟動遊戲?點擊「是」使用預設 Java 繼續啟動遊戲,\n或者請到「(全域/實例特定) 遊戲設定 → 遊戲 Java」中選取一個合適的 Java 版本。
launch.failed.sigkill=遊戲被使用者或系統強制終止。
launch.state.dependencies=處理遊戲相依元件
launch.state.done=啟動完成
@@ -670,6 +672,7 @@ message.info=提示
message.success=完成
message.unknown=未知
message.warning=警告
message.question=確認
modpack=模組包
modpack.choose=選取要安裝的遊戲模組包檔案
@@ -678,7 +681,7 @@ modpack.choose.local.detail=你可以直接將模組包檔案拖入本頁面以
modpack.choose.remote=從網路下載模組包
modpack.choose.remote.detail=需要提供模組包的下載連結
modpack.choose.repository=從 CurseForge/Modrinth 下載模組包
modpack.choose.repository.detail=下載後記得回到這個介面,把模組包拖進來哦
modpack.choose.repository.detail=可直接在跳轉到的頁面安裝模組包
modpack.choose.remote.tooltip=要下載的模組包的連結
modpack.completion=下載模組包相關檔案
modpack.desc=描述你要製作的模組包,比如模組包注意事項和更新紀錄。支援 Markdown (圖片請上傳至網路)。
@@ -747,17 +750,20 @@ modpack.wizard.step.initialization.server=點選此處查看有關伺服器自
modrinth.category.adventure=冒險
modrinth.category.atmosphere=氛圍
modrinth.category.audio=聲音
modrinth.category.babric=Babric
modrinth.category.blocks=方塊
modrinth.category.bloom=泛光
modrinth.category.bta-babric=BTA (Babric)
modrinth.category.bukkit=Bukkit
modrinth.category.bungeecord=BungeeCord
modrinth.category.canvas=Canvas
modrinth.category.cartoon=卡通
modrinth.category.challenging=高難度
modrinth.category.colored-lighting=彩色光照
modrinth.category.core-shaders=核心著色器
modrinth.category.combat=戰鬥
modrinth.category.core-shaders=核心著色器
modrinth.category.cursed=Cursed
modrinth.category.datapack=資料包
modrinth.category.decoration=裝飾
modrinth.category.economy=經濟
modrinth.category.entities=實體
@@ -765,6 +771,7 @@ modrinth.category.environment=環境
modrinth.category.equipment=裝備
modrinth.category.fabric=Fabric
modrinth.category.fantasy=幻想
modrinth.category.folia=Folia
modrinth.category.foliage=植被
modrinth.category.fonts=字體
modrinth.category.food=食物
@@ -774,7 +781,9 @@ modrinth.category.gui=GUI
modrinth.category.high=高
modrinth.category.iris=Iris
modrinth.category.items=物品
modrinth.category.java-agent=Java Agent
modrinth.category.kitchen-sink=大雜燴
modrinth.category.legacy-fabric=Legacy Fabric
modrinth.category.library=支援庫
modrinth.category.lightweight=輕量
modrinth.category.liteloader=LiteLoader
@@ -792,10 +801,12 @@ modrinth.category.models=模型
modrinth.category.modloader=ModLoader
modrinth.category.multiplayer=多人
modrinth.category.neoforge=NeoForge
modrinth.category.nilloader=NilLoader
modrinth.category.optifine=OptiFine
modrinth.category.optimization=最佳化
modrinth.category.ornithe=Ornithe
modrinth.category.paper=Paper
modrinth.category.path-tracing=路径追踪
modrinth.category.path-tracing=路徑追蹤
modrinth.category.pbr=PBR
modrinth.category.potato=極低
modrinth.category.purpur=Purpur
@@ -822,8 +833,6 @@ modrinth.category.vanilla-like=類原生
modrinth.category.velocity=Velocity
modrinth.category.waterfall=Waterfall
modrinth.category.worldgen=世界生成
modrinth.category.datapack=資料包
modrinth.category.folia=Folia
mods=模組
mods.add=新增模組
@@ -884,7 +893,7 @@ datapack.choose_datapack=選取要匯入的資料包壓縮檔
datapack.extension=資料包
datapack.title=世界 [%s] - 資料包
web.failed=加載頁面失敗
web.failed=載入頁面失敗
web.open_in_browser=是否要在瀏覽器中開啟此連結:\n%s
web.view_in_browser=在瀏覽器中查看完整日誌
@@ -892,10 +901,10 @@ world=世界
world.add=新增世界
world.backup=世界備份
world.backup.create.new_one=建立新備份
world.backup.create.failed=創建備份失敗。\n%s
world.backup.create.failed=建立備份失敗。\n%s
world.backup.create.locked=該世界正在使用中,請關閉遊戲後重試。
world.backup.create.success=成功創建新備份:%s
world.backup.delete=删除此備份
world.backup.create.success=成功建立新備份:%s
world.backup.delete=刪除此備份
world.backup.processing=正在備份中……
world.chunkbase=世界地圖
world.chunkbase.end_city=終界城地圖
@@ -934,6 +943,7 @@ world.info.player.food_level=饑餓值
world.info.player.game_type=遊戲模式
world.info.player.game_type.adventure=冒險
world.info.player.game_type.creative=創造
world.info.player.game_type.hardcore=極限
world.info.player.game_type.spectator=旁觀者
world.info.player.game_type.survival=生存
world.info.player.health=生命值
@@ -986,7 +996,7 @@ schematics.create_directory.prompt=請輸入新目錄名稱
schematics.create_directory.failed=建立目錄失敗
schematics.create_directory.failed.already_exists=目錄已存在
schematics.create_directory.failed.empty_name=名稱不能為空
schematics.create_directory.failed.invalid_name=名稱中包含非法字元
schematics.create_directory.failed.invalid_name=名稱中包含無效字元
schematics.info.description=描述
schematics.info.enclosing_size=框大小
schematics.info.name=名稱
@@ -1034,7 +1044,7 @@ settings.advanced.custom_commands.hint=自訂指令被呼叫時將包含如下
\ · $INST_FABRIC: 若安裝了 Fabric,將會存在本環境變數;\n\
\ · $INST_QUILT: 若安裝了 Quilt,將會存在本環境變數。
settings.advanced.dont_check_game_completeness=不檢查遊戲完整性
settings.advanced.dont_check_jvm_validity=不檢查 JVM 與遊戲的相容性
settings.advanced.dont_check_jvm_validity=不檢查 Java 虛擬機與遊戲的相容性
settings.advanced.dont_patch_natives=不嘗試自動取代本機庫
settings.advanced.environment_variables=環境變數
settings.advanced.game_dir.default=預設 (".minecraft/")
@@ -1044,8 +1054,8 @@ settings.advanced.java_permanent_generation_space.prompt=單位 MiB
settings.advanced.jvm=Java 虛擬機設定
settings.advanced.jvm_args=Java 虛擬機參數
settings.advanced.jvm_args.prompt=\ · 若在「Java 虛擬機參數」中輸入的參數與預設參數相同,則不會新增;\n\
\ · 若在「Java 虛擬機參數」輸入任何 GC 參數,預設參數的 G1 參數會被禁用;\n\
\ · 啟用下方「不新增預設的 JVM 參數」可在啟動遊戲時不新增預設參數。
\ · 若在「Java 虛擬機參數」輸入任何 GC 參數,預設參數的 G1 參數會被停用;\n\
\ · 啟用下方「不新增預設的 Java 虛擬機參數」可在啟動遊戲時不新增預設參數。
settings.advanced.launcher_visibility.close=遊戲啟動後結束啟動器
settings.advanced.launcher_visibility.hide=遊戲啟動後隱藏啟動器
settings.advanced.launcher_visibility.hide_and_reopen=隱藏啟動器並在遊戲結束後重新開啟
@@ -1057,8 +1067,9 @@ settings.advanced.natives_directory=本機庫路徑 (LWJGL)
settings.advanced.natives_directory.choose=選取本機庫路徑
settings.advanced.natives_directory.custom=自訂 (由你提供遊戲需要的本機庫)
settings.advanced.natives_directory.default=預設 (由啟動器提供遊戲本機庫)
settings.advanced.natives_directory.hint=本選項提供給 Apple M1 等未受遊戲官方支援的平台來自訂遊戲本機庫。如果你不知道本選項的含義,請你不要修改本選項,否則會導致遊戲無法啟動。\n\n如果你要修改本選項,你需要保證自訂目錄下有遊戲所需的本機庫檔案,如 lwjgl.dll (liblwjgl.so), openal.dll (libopenal.so) 等檔案。啟動器不會幫你補全缺少的本機庫檔案。\n\n注意:建議指定的本機庫檔案路徑使用全英文字元,否則可能導致遊戲啟動失敗。
settings.advanced.no_jvm_args=不新增預設的 JVM 參數
settings.advanced.natives_directory.default.version_id=<版本 ID>
settings.advanced.natives_directory.hint=本選項提供給 Apple Silicon 等未受遊戲官方支援的平台來自訂遊戲本機庫。如果你不知道本選項的含義,請你不要修改本選項,否則會導致遊戲無法啟動。\n\n如果你要修改本選項,你需要保證自訂目錄下有遊戲所需的本機庫檔案,如 lwjgl.dll (liblwjgl.so), openal.dll (libopenal.so) 等檔案。啟動器不會幫你補全缺少的本機庫檔案。\n\n注意:建議指定的本機庫檔案路徑使用全英文字元,否則可能導致遊戲啟動失敗。
settings.advanced.no_jvm_args=不新增預設的 Java 虛擬機參數
settings.advanced.precall_command=遊戲啟動前執行指令
settings.advanced.precall_command.prompt=將在遊戲啟動前呼叫使用
settings.advanced.process_priority=處理程式優先度
@@ -1105,7 +1116,7 @@ settings.game.java_directory.template=%s (%s)
settings.game.management=管理
settings.game.working_directory=執行路徑 (建議使用模組時選取「各實例獨立」。修改後請自行移動相關遊戲檔案,如存檔、模組設定等)
settings.game.working_directory.choose=選取執行目錄
settings.game.working_directory.hint=在「執行路徑」選項中選取「各實例獨立」使目前實例獨立存放設定、存檔、模組等資料。使用模組時建議開啟此選項以避免不同版本模組衝突。修改此選項後需自行移動存檔等檔案。
settings.game.working_directory.hint=在「執行路徑」選項中選取「各實例獨立」使目前實例獨立存放設定、存檔、模組等資料。使用模組時建議開啟此選項以避免不同實例模組衝突。修改此選項後需自行移動存檔等檔案。
settings.icon=遊戲圖示
@@ -1198,6 +1209,8 @@ update.note=開發版與預覽版包含更多的功能以及錯誤修復,但
update.latest=目前版本為最新版本
update.no_browser=無法開啟瀏覽器。網址已經複製到剪貼簿了,你可以手動複製網址開啟頁面。
update.tooltip=更新
update.preview=提前測試 HMCL 預覽版本
update.preview.tooltip=啟用此選項,你將可以提前取得 HMCL 的新版本,以便在正式發布前進行測試。
version=遊戲
version.name=遊戲實例名稱
@@ -1,6 +1,6 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
# Copyright (C) 2026 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
@@ -20,7 +20,7 @@
about=关于
about.copyright=版权
about.copyright.statement=版权所有 © 2025 huangyuhui
about.copyright.statement=版权所有 © 2013-2026 huangyuhui 及贡献者
about.author=作者
about.author.statement=bilibili @huanghongxun
about.claim=用户协议
@@ -139,7 +139,7 @@ account.methods.ban_query=检测账户是否被封禁
account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL。请下载官方版本来登录微软账户。
account.methods.microsoft.snapshot.website=官方网站
account.methods.offline=离线模式
account.methods.offline.name.special_characters=建议使用英文字符、数字以及下划线命名
account.methods.offline.name.special_characters=建议使用英文字符、数字以及下划线命名,且长度不超过 16 个字符
account.methods.offline.name.invalid=游戏用户名建议仅使用英文字母、数字及下划线,且长度不超过 16 个字符。\n\
\n\
\ · 一些合法用户名:HuangYu、huang_Yu、Huang_Yu_123;\n\
@@ -181,7 +181,7 @@ archive.version=版本
assets.download=下载资源
assets.download_all=检查资源文件完整性
assets.index.malformed=资源文件的索引文件损坏。你可以在相应版本的“版本管理”页面中,点击左下角“管理 → 更新游戏资源文件”以修复该问题。\n你可以点击右上角帮助按钮进行求助。
assets.index.malformed=资源文件的索引文件损坏。你可以在相应实例的“实例管理”页面中,点击左下角“管理 → 更新游戏资源文件”以修复该问题。\n你可以点击右上角帮助按钮进行求助。
button.cancel=取消
button.change_source=切换下载源
@@ -194,6 +194,7 @@ button.export=导出
button.no=否
button.ok=确定
button.ok.countdown=确定 (%d)
button.reveal_dir=打开文件夹
button.refresh=刷新
button.remove=删除
button.remove.confirm=你确定要删除吗?此操作无法撤销!
@@ -369,7 +370,7 @@ exception.access_denied=无法访问文件“%s”。HMCL 没有对该文件的
对于 Windows 用户,你还可以尝试通过资源监视器查看是否有程序占用了该文件。如果是,请关闭占用该文件的程序,或者重启电脑再试。\n\
如遇到问题,你可以点击右上角帮助按钮进行求助。
exception.artifact_malformed=下载的文件无法通过校验。\n你可以点击右上角帮助按钮进行求助。
exception.ssl_handshake=无法建立 SSL 连接。当前 Java 虚拟机缺少相关的 SSL 证书。你可以尝试使用其他 Java 虚拟机启动 HMCL 再试。\n你可以点击右上角帮助按钮进行求助。
exception.ssl_handshake=无法建立 SSL 连接。当前 Java 缺少相关的 SSL 证书。你可以尝试使用其他 Java 启动 HMCL 再试。\n你可以点击右上角帮助按钮进行求助。
extension.bat=Windows 脚本
extension.mod=模组文件
@@ -385,16 +386,17 @@ fatal.config_change_owner_root=你正在使用 root 账户启动 Hello Minecraft
fatal.config_in_temp_dir=你正在临时文件夹中启动 Hello Minecraft! Launcher,你的设置和游戏数据可能会丢失。建议将 HMCL 移动至其他位置再启动。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。\n是否继续启动?
fatal.config_loading_failure=Hello Minecraft! Launcher 无法加载配置文件。\n请确保 HMCL 对“%s”文件夹及该文件夹下的文件拥有读写权限。\n对于 macOS,尝试将 HMCL 放在除“桌面”“下载”“文稿”之外的有权限的地方再试。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.config_loading_failure.unix=Hello Minecraft! Launcher 无法加载配置文件,因为配置文件是由用户“%1$s”创建的。\n请使用 root 账户启动 HMCL (不推荐),或在终端中执行以下命令将配置文件的所有权变更为当前用户:\n%2$s\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.config_unsupported_version=当前配置文件是由更高版本的 Hello Minecraft! Launcher 创建的,当前版本的 HMCL 无法正常加载。请更新并重启 HMCL。\n在更新启动器之前,你修改的所有设置都不会被保存。\n如果遇到问题,你可以点击右上角帮助按钮进行求助。
fatal.mac_app_translocation=由于 macOS 的安全机制,Hello Minecraft! Launcher 被系统隔离至临时文件夹中。\n请将 HMCL 移动到其他文件夹后再尝试启动,否则你的设置和游戏数据可能会在重启后丢失。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。\n是否继续启动?
fatal.migration_requires_manual_reboot=Hello Minecraft! Launcher 即将完成升级,请重新打开 HMCL。\n如遇到问题,你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.apply_update_failure=我们很抱歉 Hello Minecraft! Launcher 无法自动完成升级,因为出现了一些问题。\n但你依可以从 %s 手动下载 HMCL 来完成升级。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.apply_update_need_win7=Hello Minecraft! Launcher 无法在 Windows XP/Vista 上进行自动更新。请从 %s 手动下载 HMCL 来完成升级。
fatal.deprecated_java_version=HMCL 未来需要 Java 11 或更高版本才能运行,但依然支持使用 Java 8 启动游戏。建议安装最新版本的 Java 以确保 HMCL 能正常工作。\n你可以继续保留旧版本 Java。HMCL 能够识别与管理多个 Java,并会自动根据游戏版本为你选择合适的 Java。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.deprecated_java_version.update=更高版本的 HMCL 需要 Java 11 或更高版本才能运行,请安装最新版本的 Java 以确保 HMCL 能够完成升级。\n你可以继续保留旧版本 Java。HMCL 能够识别与管理多个 Java,并会自动根据游戏版本为你选择合适的 Java。
fatal.deprecated_java_version=HMCL 未来需要 Java 17 或更高版本才能运行,但依然支持使用 Java 6~16 启动游戏。建议安装最新版本的 Java 以确保 HMCL 能正常工作。\n你可以继续保留旧版本 Java。HMCL 能够识别与管理多个 Java,并会自动根据游戏版本为你选择合适的 Java。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.deprecated_java_version.update=更高版本的 HMCL 需要 Java 17 或更高版本才能运行,请安装最新版本的 Java 以确保 HMCL 能够完成升级。\n你可以继续保留旧版本 Java。HMCL 能够识别与管理多个 Java,并会自动根据游戏版本为你选择合适的 Java。
fatal.deprecated_java_version.download_link=下载 Java %d
fatal.samba=如果你正在通过 Samba 共享的文件夹中运行 Hello Minecraft! Launcher,启动器可能无法正常工作。请尝试更新你的 Java 或在本地文件夹内运行 HMCL。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.illegal_char=由于你的用户文件夹路径中存在非法字符“=”,你将无法使用外置登录账户以及离线登录更换皮肤功能。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
fatal.unsupported_platform=Minecraft 尚未对你的平台提供完善支持,所以可能影响游戏体验或无法启动游戏。\n若无法启动 Minecraft 1.17 及更高版本,可以尝试在“(全局/版本特定) 游戏设置 → 高级设置 → 调试选项”中将“渲染器”切换为“软渲染器”,以获得更好的兼容性。\n如遇到问题,你可以点击右上角帮助按钮进行求助。
fatal.unsupported_platform=Minecraft 尚未对你的平台提供完善支持,所以可能影响游戏体验或无法启动游戏。\n若无法启动 Minecraft 1.17 及更高版本,可以尝试在“(全局/实例特定) 游戏设置 → 高级设置 → 调试选项”中将“渲染器”切换为“软渲染器”,以获得更好的兼容性。\n如遇到问题,你可以点击右上角帮助按钮进行求助。
fatal.unsupported_platform.loongarch=Hello Minecraft! Launcher 已为龙芯提供支持。\n如果遇到问题,你可以点击右上角帮助按钮进行求助。
fatal.unsupported_platform.macos_arm64=Hello Minecraft! Launcher 已为 Apple Silicon 平台提供支持。使用 ARM 原生 Java 启动游戏以获得更流畅的游戏体验。\n如果你在游戏中遇到问题,使用 x86-64 架构的 Java 启动游戏可能有更好的兼容性。\n如遇到问题,你可以点击右上角帮助按钮进行求助。
fatal.unsupported_platform.windows_arm64=Hello Minecraft! Launcher 已为 Windows on Arm 平台提供原生支持。如果你在游戏中遇到问题,请尝试使用 x86 架构的 Java 启动游戏。\n如果你正在使用 <b>高通</b> 平台,你可能需要安装 <a href="ms-windows-store://pdp/?productid=9NQPSL29BFFF">OpenGL 兼容包</a> 后才能进行游戏。点击链接前往 Microsoft Store 安装兼容包。\n如遇到问题,你可以点击右上角帮助按钮进行求助。
@@ -411,7 +413,7 @@ feedback.qq_group.statement=欢迎加入 HMCL 用户群,加入后请遵守群
file=文件
folder.config=配置文件夹
folder.game=游戏文件夹
folder.game=实例运行文件夹
folder.logs=日志文件夹
folder.mod=模组文件夹
folder.resourcepacks=资源包文件夹
@@ -426,14 +428,14 @@ game.crash.feedback=<b>请不要将本界面截图给他人!</b>如果你要
game.crash.info=游戏信息
game.crash.reason=崩溃原因
game.crash.reason.analyzing=分析中……
game.crash.reason.block=当前游戏由于某个方块不能正常工作,无法继续运行。\n你可以尝试使用 <a href="https://www.mcedit.net">MCEdit</a> 工具编辑存档删除该方块,或者直接删除对应的模组。\n方块类型:%1$s\n方块坐标:%2$s
game.crash.reason.block=当前游戏由于某个方块不能正常工作,无法继续运行。\n你可以尝试使用地图编辑工具编辑存档删除该方块,或者直接删除对应的模组。\n方块类型:%1$s\n方块坐标:%2$s\n\n相关工具:<a href="https://minecraft.wiki/w/Tutorial:Programs_and_editors/Mapping#Map_editors">英文 Wiki</a> | <a href="https://zh.minecraft.wiki/w/辅助程序与编辑器/地图工具?variant=zh-cn#地图编辑工具">中文 Wiki</a>
game.crash.reason.bootstrap_failed=当前游戏由于模组“%1$s”出现问题,无法继续运行。\n你可以尝试删除或更新该模组以解决问题。
game.crash.reason.mixin_apply_mod_failed=当前游戏由于 Mixin 无法应用于“%1$s”模组,无法继续运行。\n你可以尝试删除或更新该模组以解决问题。
game.crash.reason.config=当前游戏由于无法解析模组配置文件,无法继续运行。\n无法解析模组“%1$s”的配置文件“%2$s”。
game.crash.reason.multiple=检测到多个原因:\n\n
game.crash.reason.debug_crash=当前游戏由于手动触发崩溃,无法继续运行。\n事实上游戏并没有问题,问题都是你造成的!
game.crash.reason.duplicated_mod=当前游戏由于模组“%1$s”重复安装,无法继续运行。\n%2$s\n每种模组只能安装一个,请你删除多余的模组再试。
game.crash.reason.entity=当前游戏由于某个实体不能正常工作,无法继续运行。\n你可以尝试使用 <a href="https://www.mcedit.net">MCEdit</a> 工具编辑存档删除该实体,或者直接删除对应的模组。\n实体类型:%1$s\n实体坐标:%2$s
game.crash.reason.entity=当前游戏由于某个实体不能正常工作,无法继续运行。\n你可以尝试使用地图编辑工具编辑存档删除该实体,或者直接删除对应的模组。\n实体类型:%1$s\n实体坐标:%2$s\n\n相关工具:<a href="https://minecraft.wiki/w/Tutorial:Programs_and_editors/Mapping#Map_editors">英文 Wiki</a> | <a href="https://zh.minecraft.wiki/w/辅助程序与编辑器/地图工具?variant=zh-cn#地图编辑工具">中文 Wiki</a>
game.crash.reason.fabric_version_0_12=Fabric Loader 0.12 及更高版本与当前已经安装的模组可能不兼容,你需要将 Fabric Loader 降级至 0.11.7。
game.crash.reason.fabric_warnings=Fabric 提供了一些警告信息:\n%1$s
game.crash.reason.file_already_exists=当前游戏由于文件“%1$s”已经存在,无法继续运行。\n如果你认为这个文件可以删除,你可以在备份这个文件后尝试删除它,并重新启动游戏。
@@ -447,12 +449,12 @@ game.crash.reason.graphics_driver=当前游戏由于显卡驱动问题而崩溃
game.crash.reason.macos_failed_to_find_service_port_for_display=当前游戏由于 Apple Silicon 平台下初始化 OpenGL 窗口失败,无法继续运行。\n对于该问题,HMCL 暂无直接性的解决方案。请你尝试任意打开一个浏览器并全屏,然后再回到 HMCL 启动游戏。在弹出游戏窗口前<b>迅速切回浏览器页面</b>,等待游戏窗口出现后再切回游戏窗口。
game.crash.reason.illegal_access_error=当前游戏由于某些模组的问题,无法继续运行。\n如果你认识“%1$s”,你可以更新或删除对应模组再试。
game.crash.reason.install_mixinbootstrap=当前游戏由于缺失 MixinBootstrap,无法继续运行。\n你可以尝试安装 <a href="https://www.curseforge.com/minecraft/mc-mods/mixinbootstrap">MixinBootstrap</a> 解决该问题。若安装后崩溃,可以尝试在该模组的文件名开头添加半角感叹号 (!) 解决。
game.crash.reason.need_jdk11=当前游戏由于 Java 虚拟机版本不合适,无法继续运行。\n你需要下载安装 <a href="https://bell-sw.com/pages/downloads/#downloads">Java 11</a>,并在“(全局/版本特定) 游戏设置 → 游戏 Java”中将 Java 设置为 11.x 的版本。
game.crash.reason.jdk_9=当前游戏由于 Java 版本过高,无法继续运行。\n你需要下载安装 <a href="https://bell-sw.com/pages/downloads/#downloads">Java 8</a>,并在“(全局/版本特定) 游戏设置 → 游戏 Java”中将 Java 设置为 1.8.x 的版本。
game.crash.reason.jvm_32bit=当前游戏由于内存分配过大,超过了 32 位 Java 内存限制,无法继续运行。\n如果你的电脑是 64 位系统,请下载安装并更换 64 位 Java。<a href="https://bell-sw.com/pages/downloads/#downloads">下载 Java</a>\n如果你的电脑是 32 位系统,你或许可以重新安装 64 位系统,或换一台新电脑。\n或者,你可以在“(全局/版本特定) 游戏设置 → 游戏内存”中关闭“自动分配内存”,并把内存分配值调整为 1024 MiB 或以下。
game.crash.reason.need_jdk11=当前游戏由于 Java 版本不合适,无法继续运行。\n你需要下载安装 <a href="https://bell-sw.com/pages/downloads/#downloads">Java 11</a>,并在“(全局/实例特定) 游戏设置 → 游戏 Java”中将 Java 设置为 11.x 的版本。
game.crash.reason.jdk_9=当前游戏由于 Java 版本过高,无法继续运行。\n你需要下载安装 <a href="https://bell-sw.com/pages/downloads/#downloads">Java 8</a>,并在“(全局/实例特定) 游戏设置 → 游戏 Java”中将 Java 设置为 1.8.x 的版本。
game.crash.reason.jvm_32bit=当前游戏由于内存分配过大,超过了 32 位 Java 虚拟机内存限制,无法继续运行。\n如果你的电脑是 64 位系统,请下载安装并更换 64 位 Java。<a href="https://bell-sw.com/pages/downloads/#downloads">下载 Java</a>\n如果你的电脑是 32 位系统,你或许可以重新安装 64 位系统,或换一台新电脑。\n或者,你可以在“(全局/实例特定) 游戏设置 → 游戏内存”中关闭“自动分配内存”,并把内存分配值调整为 1024 MiB 或以下。
game.crash.reason.loading_crashed_forge=当前游戏由于模组“%1$s (%2$s)”错误,无法继续运行。\n你可以尝试删除或更新该模组以解决问题。
game.crash.reason.loading_crashed_fabric=当前游戏由于模组“%1$s”错误,无法继续运行。\n你可以尝试删除或更新该模组以解决问题。
game.crash.reason.memory_exceeded=当前游戏由于内存分配过大,无法继续运行。\n该问题是由于系统页面文件太小导致的。\n你需要在“(全局/版本特定) 游戏设置”中关闭“自动分配内存”,并将内存分配值调低至游戏能正常启动为止。\n你还可以尝试将虚拟内存设置调整为“自动管理所有驱动器分页文件大小”,<a href="https://docs.hmcl.net/assets/img/hmcl/自动管理所有驱动器分页文件大小.webp">详情</a>。
game.crash.reason.memory_exceeded=当前游戏由于内存分配过大,无法继续运行。\n该问题是由于系统页面文件太小导致的。\n你需要在“(全局/实例特定) 游戏设置”中关闭“自动分配内存”,并将内存分配值调低至游戏能正常启动为止。\n你还可以尝试将虚拟内存设置调整为“自动管理所有驱动器分页文件大小”,<a href="https://docs.hmcl.net/assets/img/hmcl/自动管理所有驱动器分页文件大小.webp">详情</a>。
game.crash.reason.mac_jdk_8u261=当前游戏由于你所使用的 Forge/OptiFine 与 Java 冲突而崩溃。\n请尝试更新 Forge/OptiFine,或使用 Java 8u251 及更早版本启动。
game.crash.reason.mod=当前游戏由于“%1$s”的问题,无法继续运行。\n你可以更新或删除已经安装的“%1$s”再试。
game.crash.reason.mod_resolution=当前游戏由于模组依赖问题,无法继续运行。Fabric 提供了如下信息:\n%1$s
@@ -462,37 +464,37 @@ game.crash.reason.mod_resolution_missing=当前游戏由于缺少前置模组,
game.crash.reason.mod_resolution_missing_minecraft=当前游戏由于模组和 Minecraft 游戏版本不匹配,无法继续运行。\n“%1$s”需要 Minecraft %2$s 才能运行。\n如果你要继续使用你已经安装的模组,你可以选择安装对应的 Minecraft 版本。如果你要继续使用当前 Minecraft 版本,你需要安装对应版本的模组。
game.crash.reason.mod_resolution_mod_version=%1$s (版本号 %2$s)
game.crash.reason.mod_resolution_mod_version.any=%1$s (任意版本)
game.crash.reason.forge_repeat_installation=当前游戏由于 Forge 重复安装,无法继续运行。<a href="https://github.com/HMCL-dev/HMCL/issues/1880">此为已知问题</a>\n建议将日志上传并反馈至 GitHub,以便我们找到更多线索并修复此问题。\n目前你可以在“版本管理 → 自动安装”中卸载 Forge 并重新安装。
game.crash.reason.optifine_repeat_installation=当前游戏由于 OptiFine 重复安装,无法继续运行。\n请删除模组文件夹下的 OptiFine 或前往“版本管理 → 自动安装”卸载安装的 OptiFine。
game.crash.reason.forge_repeat_installation=当前游戏由于 Forge 重复安装,无法继续运行。<a href="https://github.com/HMCL-dev/HMCL/issues/1880">此为已知问题</a>\n建议将日志上传并反馈至 GitHub,以便我们找到更多线索并修复此问题。\n目前你可以在“实例管理 → 自动安装”中卸载 Forge 并重新安装。
game.crash.reason.optifine_repeat_installation=当前游戏由于 OptiFine 重复安装,无法继续运行。\n请删除模组文件夹下的 OptiFine 或前往“实例管理 → 自动安装”卸载安装的 OptiFine。
game.crash.reason.forgemod_resolution=当前游戏由于模组依赖问题,无法继续运行。Forge/NeoForge 提供了如下信息:\n%1$s
game.crash.reason.forge_found_duplicate_mods=当前游戏由于模组重复安装,无法继续运行。Forge/NeoForge 提供了如下信息:\n%1$s
game.crash.reason.modmixin_failure=当前游戏由于某些模组注入失败,无法继续运行。\n这一般代表着该模组存在问题,或与当前环境不兼容。\n你可以查看日志寻找出错模组。
game.crash.reason.night_config_fixes=当前游戏由于 Night Config 库的一些问题,无法继续运行。\n你可以尝试安装 <a href="https://www.curseforge.com/minecraft/mc-mods/night-config-fixes">Night Config Fixes</a> 模组,这或许能帮助你解决这个问题。\n更多详情,可访问该模组的 <a href="https://github.com/Fuzss/nightconfigfixes">GitHub 仓库</a>。
game.crash.reason.forge_error=Forge/NeoForge 可能已经提供了错误信息。\n你可以查看日志,并根据错误报告中的日志信息进行对应处理。\n如果没有看到报错信息,可以查看错误报告了解错误具体是如何发生的。\n%1$s
game.crash.reason.mod_resolution0=当前游戏由于一些模组出现问题,无法继续运行。\n你可以查看日志寻找出错模组。
game.crash.reason.java_version_is_too_high=当前游戏由于 Java 虚拟机版本过高,无法继续运行。\n请在“(全局/版本特定) 游戏设置 → 游戏 Java”中改用较低版本的 Java,然后再启动游戏。\n如果没有,可以从 <a href="https://www.java.com/download/">java.com (Java 8)</a> 或 <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java 17)</a> 等平台下载、安装一个 (安装完后需重启启动器)。
game.crash.reason.java_version_is_too_high=当前游戏由于 Java 版本过高,无法继续运行。\n请在“(全局/实例特定) 游戏设置 → 游戏 Java”中改用较低版本的 Java,然后再启动游戏。\n如果没有,可以从 <a href="https://www.java.com/download/">java.com (Java 8)</a> 或 <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java 17)</a> 等平台下载、安装一个 (安装完后需重启启动器)。
game.crash.reason.mod_name=当前游戏由于模组文件名称问题,无法继续运行。\n模组文件名称应只使用半角的大小写字母 (Aa~Zz)、数字 (0~9)、横线 (-)、下划线 (_)和点 (.)。\n请到模组文件夹中将所有不合规的模组文件名修改为上述合规字符。
game.crash.reason.incomplete_forge_installation=当前游戏由于 Forge/NeoForge 安装不完整,无法继续运行。\n请在“版本管理 → 自动安装”中卸载 Forge 并重新安装。
game.crash.reason.optifine_is_not_compatible_with_forge=当前游戏由于 OptiFine 与当前版本的 Forge 不兼容,导致游戏崩溃。\n点击 <a href="https://zkitefly.github.io/optifine-forge-support-list">此处</a> 查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏或在“版本管理 → 自动安装”中更换版本。\n经测试,Forge 版本过高或过低都可能导致崩溃。
game.crash.reason.incomplete_forge_installation=当前游戏由于 Forge/NeoForge 安装不完整,无法继续运行。\n请在“实例管理 → 自动安装”中卸载 Forge 并重新安装。
game.crash.reason.optifine_is_not_compatible_with_forge=当前游戏由于 OptiFine 与当前版本的 Forge 不兼容,导致游戏崩溃。\n点击 <a href="https://zkitefly.github.io/optifine-forge-support-list">此处</a> 查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏或在“实例管理 → 自动安装”中更换版本。\n经测试,Forge 版本过高或过低都可能导致崩溃。
game.crash.reason.mod_files_are_decompressed=当前游戏由于模组文件被解压了,无法继续运行。\n请直接把整个模组文件放进模组文件夹中即可。\n解压模组文件会导致游戏出错。请删除模组文件夹中已被解压的模组,然后再启动游戏。
game.crash.reason.shaders_mod=当前游戏由于同时安装了 OptiFine 和 Shaders 模组,无法继续运行。\n由于 OptiFine 已集成 Shaders 模组的功能,所以只需删除 Shaders 模组即可。
game.crash.reason.rtss_forest_sodium=当前游戏由于 RivaTuner Statistics Server (RTSS) 与 Sodium 不兼容,导致游戏崩溃。\n点击 <a href="https://github.com/CaffeineMC/sodium-fabric/wiki/Known-Issues#rtss-incompatible">此处</a> 查看详情。
game.crash.reason.too_many_mods_lead_to_exceeding_the_id_limit=当前游戏由于你所安装的模组过多,超出了游戏的 ID 限制,无法继续运行。\n请尝试安装 <a href="https://www.curseforge.com/minecraft/mc-mods/jeid">JEID</a> 等修复模组,或删除部分大型模组。
game.crash.reason.optifine_causes_the_world_to_fail_to_load=当前游戏可能由于 OptiFine 而无法继续运行。\n该问题只在特定 OptiFine 版本中出现,你可以尝试在“版本管理 → 自动安装”中更换 OptiFine 的版本。
game.crash.reason.optifine_causes_the_world_to_fail_to_load=当前游戏可能由于 OptiFine 而无法继续运行。\n该问题只在特定 OptiFine 版本中出现,你可以尝试在“实例管理 → 自动安装”中更换 OptiFine 的版本。
game.crash.reason.modlauncher_8=当前游戏由于你所使用的 Forge 版本与当前使用的 Java 冲突而崩溃。请尝试更新 Forge 到 36.2.26 或更高版本或换用版本低于 1.8.0.320 的 Java。<a href="https://bell-sw.com/pages/downloads/?version=java-8&package=jre-full">Liberica JDK 8u312+7</a>
game.crash.reason.no_class_def_found_error=当前游戏由于代码不完整,无法继续运行。\n你的游戏可能缺失了某个模组,或者某些模组文件不完整,或者模组与游戏的版本不匹配。\n你可能需要重新安装游戏和模组,或寻求他人帮助。\n缺失:\n%1$s
game.crash.reason.no_such_method_error=当前游戏由于代码不完整,无法继续运行。\n你的游戏可能缺失了某个模组,或者某些模组文件不完整,或者模组与游戏的版本不匹配。\n你可能需要重新安装游戏和模组,或寻求他人帮助。
game.crash.reason.opengl_not_supported=当前游戏由于你的显卡驱动存在问题,无法继续运行。\n原因是 OpenGL 不受支持,你现在是否在远程桌面或者串流模式下?如果是,请直接使用原电脑启动游戏。\n或者尝试升级你的显卡驱动到最新版本后再尝试启动游戏。如果你的电脑同时存在独立显卡和集成显卡,你需要检查游戏是否使用集成显卡启动。如果是,请尝试使用独立显卡启动 HMCL 与游戏。如果仍有问题,你可能需要考虑换一个新显卡或新电脑。
game.crash.reason.openj9=当前游戏无法在 OpenJ9 虚拟机上运行。请你在“(全局/版本特定) 游戏设置 → 游戏 Java”中更换 Hotspot Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以在网上自行下载。
game.crash.reason.out_of_memory=当前游戏由于内存不足,无法继续运行。\n这可能是内存分配过小,或者模组数量过多导致的。\n你可以在“(全局/版本特定) 游戏设置 → 游戏内存”中调整内存分配值以允许游戏在更大内存下运行。\n如果仍然出现该错误,你可能需要换一台更好的电脑。
game.crash.reason.openj9=当前游戏无法在 OpenJ9 虚拟机上运行。请你在“(全局/实例特定) 游戏设置 → 游戏 Java”中更换为使用 Hotspot 虚拟机的 Java,并重新启动游戏。如果没有下载安装,你可以在网上自行下载。
game.crash.reason.out_of_memory=当前游戏由于内存不足,无法继续运行。\n这可能是内存分配过小,或者模组数量过多导致的。\n你可以在“(全局/实例特定) 游戏设置 → 游戏内存”中调整内存分配值以允许游戏在更大内存下运行。\n如果仍然出现该错误,你可能需要换一台更好的电脑。
game.crash.reason.resolution_too_high=当前游戏由于资源包/纹理包分辨率过高,无法继续运行。\n你可以更换一个分辨率更低的资源包/纹理包,或者更换一个显存更大的显卡。
game.crash.reason.stacktrace=原因未知。请点击日志按钮查看详细信息。\n下面是一些关键词,其中可能包含模组名称,你可以通过搜索的方式查找有关信息。\n%s
game.crash.reason.too_old_java=当前游戏由于 Java 虚拟机版本过低,无法继续运行。\n你需要在“(全局/版本特定) 游戏设置 → 游戏 Java”中更换 Java %1$s 或更新版本的 Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以点击 <a href="https://learn.microsoft.com/java/openjdk/download">此处</a> 下载 Microsoft JDK。
game.crash.reason.too_old_java=当前游戏由于 Java 版本过低,无法继续运行。\n你需要在“(全局/实例特定) 游戏设置 → 游戏 Java”中更换 Java %1$s 或更新版本的 Java,并重新启动游戏。如果没有下载安装,你可以点击 <a href="https://learn.microsoft.com/java/openjdk/download">此处</a> 下载 Microsoft JDK。
game.crash.reason.unknown=原因未知。请点击日志按钮查看详细信息。
game.crash.reason.unsatisfied_link_error=当前游戏由于缺少本地库,无法继续运行。\n这些本地库缺失:%1$s。\n如果你在“(全局/版本特定) 游戏设置 → 高级设置”中修改了本地库路径选项,请你修改回默认模式。\n如果你正在使用默认模式,请检查游戏文件夹路径是否只包含英文字母、数字和下划线。\n如果是,那么请检查是否为模组或 HMCL 导致了本地库缺失的问题。如果你确定是 HMCL 引起的,建议你向我们反馈。\n<b>对于 Windows 用户,你还可以尝试在“控制面板 → 时钟和区域 → 区域 → 管理 → 更改系统区域设置”中将“当前系统区域设置”修改为“中文(简体,中国大陆)”,并关闭“Beta 版:使用 Unicode UTF-8 提供全球语言支持”选项;</b>\n<b>或将游戏文件夹路径中的所有非英文字符的名称 (例如中文、空格等) 修改为英文字符。</b>\n如果你确实需要自定义本地库路径,你需要保证其中包含缺失的本地库!
game.crash.reason.unsatisfied_link_error=当前游戏由于缺少本地库,无法继续运行。\n这些本地库缺失:%1$s。\n如果你在“(全局/实例特定) 游戏设置 → 高级设置”中修改了本地库路径选项,请你修改回默认模式。\n如果你正在使用默认模式,请检查游戏文件夹路径是否只包含英文字母、数字和下划线。\n如果是,那么请检查是否为模组或 HMCL 导致了本地库缺失的问题。如果你确定是 HMCL 引起的,建议你向我们反馈。\n<b>对于 Windows 用户,你还可以尝试在“控制面板 → 时钟和区域 → 区域 → 管理 → 更改系统区域设置”中将“当前系统区域设置”修改为“中文(简体,中国大陆)”,并关闭“Beta 版:使用 Unicode UTF-8 提供全球语言支持”选项;</b>\n<b>或将游戏文件夹路径中的所有非英文字符的名称 (例如中文、空格等) 修改为英文字符。</b>\n如果你确实需要自定义本地库路径,你需要保证其中包含缺失的本地库!
game.crash.title=游戏意外退出
game.directory=游戏文件夹路径
game.version=游戏版本
game.version=游戏实例
help=帮助
help.doc=Hello Minecraft! Launcher 帮助文档
@@ -503,7 +505,7 @@ input.number=必须是数字
input.not_empty=必填项
input.url=必须是合法的链接
install=添加游戏
install=添加实例
install.change_version=更换版本
install.change_version.confirm=你确定要将 %s 从 %s 更换成 %s 吗?
install.change_version.process=更换版本
@@ -545,8 +547,8 @@ install.modpack=安装整合包
install.modpack.installation=安装整合包
install.name.invalid=名称中包含非 ASCII 字符(如 Emoji 表情或中文字符)。\n建议修改名称。名称建议仅包含英文字母、数字和下划线,以防启动游戏时出现问题。是否继续安装?
install.new_game=安装新游戏
install.new_game.already_exists=此版本已经存在,请换一个名字
install.new_game.current_game_version=当前游戏版本
install.new_game.already_exists=此实例已经存在,请换一个名字
install.new_game.current_game_version=当前游戏实例
install.new_game.installation=安装新游戏
install.new_game.malformed=名字不合法
install.select=请选择安装方式
@@ -588,10 +590,10 @@ lang.default=跟随系统语言
launch.advice=%s 是否继续启动?
launch.advice.multi=检测到以下问题:\n\n%s\n\n这些问题可能导致游戏无法正常启动或影响游戏体验,是否继续启动?\n你可以点击右上角帮助按钮进行求助。
launch.advice.java.auto=当前选择的 Java 虚拟机版本不满足游戏要求。\n点击“是”即可由 HMCL 来自动选取合适的 Java 虚拟机版本。\n或者你可以在“(全局/版本特定) 游戏设置 → 游戏 Java”中选择一个合适的 Java 虚拟机版本。
launch.advice.java.auto=当前选择的 Java 版本不满足游戏要求。\n点击“是”即可由 HMCL 来自动选取合适的 Java 版本。\n或者你可以在“(全局/实例特定) 游戏设置 → 游戏 Java”中选择一个合适的 Java 版本。
launch.advice.java.modded_java_7=Minecraft 1.7.2 及更低版本需要 Java 7 及更低版本。
launch.advice.corrected=我们已经修复了 Java 虚拟机版本问题。如果你确实希望使用你自定义的 Java 虚拟机,你可以在“(全局/版本特定) 游戏设置 → 高级设置”中往下滑,启用“不检查 JVM 与游戏的兼容性”。
launch.advice.uncorrected=如果你确实希望使用你自定义的 Java 虚拟机,你可以在“(全局/版本特定) 游戏设置 → 高级设置”中往下滑,启用“不检查 JVM 与游戏的兼容性”。
launch.advice.corrected=我们已经修复了 Java 版本问题。如果你确实希望使用你自定义的 Java,你可以在“(全局/实例特定) 游戏设置 → 高级设置”中往下滑,启用“不检查 Java 虚拟机与游戏的兼容性”。
launch.advice.uncorrected=如果你确实希望使用你自定义的 Java,你可以在“(全局/实例特定) 游戏设置 → 高级设置”中往下滑,启用“不检查 Java 虚拟机与游戏的兼容性”。
launch.advice.different_platform=你正在使用 32 位 Java 启动游戏。建议更换至 64 位 Java。
launch.advice.forge2760_liteloader=Forge 14.23.5.2760 与 LiteLoader 不兼容。请更新 Forge 至 14.23.5.2773 或更高版本。
launch.advice.forge28_2_2_optifine=Forge 28.2.2 及更高版本与 OptiFine 不兼容。请降级 Forge 至 28.2.1 或更低版本。
@@ -609,7 +611,7 @@ launch.advice.vanilla_linux_java_8=对于 Linux x86-64 平台,Minecraft 1.12.2
launch.advice.vanilla_x86.translation=Minecraft 尚未为你的平台提供完善支持,所以可能影响游戏体验或无法启动游戏。\n你可以在 <a href="https://learn.microsoft.com/java/openjdk/download">这里</a> 下载 <b>x86-64</b> 架构的 Java 以获得更完整的体验。
launch.advice.unknown=由于以下原因,无法继续启动游戏:
launch.failed=启动失败
launch.failed.cannot_create_jvm=无法创建 Java 虚拟机。可能是 Java 参数有问题,你可以在“(全局/版本特定) 游戏设置 → 高级设置 → Java 虚拟机设置”中移除所有 Java 虚拟机参数后,尝试再次启动游戏。
launch.failed.cannot_create_jvm=无法创建 Java 虚拟机。可能是虚拟机参数有问题。你可以在“(全局/实例特定) 游戏设置 → 高级设置 → Java 虚拟机设置”中移除所有虚拟机参数后,尝试再次启动游戏。
launch.failed.creating_process=启动失败。在创建新进程时发生错误,可能是 Java 路径错误。
launch.failed.command_too_long=命令长度超过限制,无法创建批处理脚本。请导出为 PowerShell 脚本。
launch.failed.decompressing_natives=未能解压游戏本地库。
@@ -620,7 +622,7 @@ launch.failed.execution_policy.failed_to_set=设置执行策略失败
launch.failed.execution_policy.hint=当前执行策略阻止你执行 PowerShell 脚本。\n点击“确定”允许当前用户执行本地 PowerShell 脚本,或点击“取消”保持现状。
launch.failed.exited_abnormally=游戏非正常退出。请查看日志文件,或联系他人寻求帮助。
launch.failed.java_version_too_low=你所指定的 Java 版本过低。请重新设置 Java 版本。
launch.failed.no_accepted_java=找不到适合当前游戏使用的 Java。是否使用默认 Java 启动游戏?点击“是”使用默认 Java 继续启动游戏,\n或者在“(全局/版本特定) 游戏设置 → 游戏 Java”中选择一个合适的 Java 虚拟机版本。\n你可以点击右上角帮助按钮进行求助。
launch.failed.no_accepted_java=找不到适合当前游戏使用的 Java。是否使用默认 Java 启动游戏?点击“是”使用默认 Java 继续启动游戏,\n或者在“(全局/实例特定) 游戏设置 → 游戏 Java”中选择一个合适的 Java 版本。\n你可以点击右上角帮助按钮进行求助。
launch.failed.sigkill=游戏被用户或系统强制终止。
launch.state.dependencies=处理游戏依赖
launch.state.done=启动完成
@@ -680,6 +682,7 @@ message.info=提示
message.success=完成
message.unknown=未知
message.warning=警告
message.question=确认
modpack=整合包
modpack.choose=选择要安装的游戏整合包文件
@@ -688,7 +691,7 @@ modpack.choose.local.detail=你可以直接将整合包文件拖入本页面以
modpack.choose.remote=从互联网下载整合包
modpack.choose.remote.detail=需要提供整合包的下载链接
modpack.choose.repository=从 CurseForge/Modrinth 下载整合包
modpack.choose.repository.detail=下载后记得回到这个界面,把整合包拖进来哦
modpack.choose.repository.detail=可直接在跳转到的页面安装整合包
modpack.choose.remote.tooltip=要下载的整合包的链接
modpack.completion=下载整合包相关文件
modpack.desc=描述你要制作的整合包,比如整合包注意事项和更新记录。支持 Markdown (图片请用网络链接)。
@@ -747,27 +750,30 @@ modpack.wizard.step.2=文件选择
modpack.wizard.step.2.title=选中你想添加到整合包中的文件或文件夹
modpack.wizard.step.3=整合包类型
modpack.wizard.step.3.title=选择整合包导出类型
modpack.wizard.step.initialization.exported_version=要导出的游戏版本
modpack.wizard.step.initialization.exported_version=要导出的游戏实例
modpack.wizard.step.initialization.force_update=强制升级整合包至最新版本 (需要自建服务器)
modpack.wizard.step.initialization.include_launcher=包含启动器
modpack.wizard.step.initialization.save=选择要导出到的游戏整合包位置
modpack.wizard.step.initialization.warning=在制作整合包前,请你确认你选择的版本可以正常启动,\n并保证你的 Minecraft 是正式版而非快照,\n而且不应当将不允许非官方途径传播的模组、资源 (纹理) 包等纳入整合包。\n整合包会保存你目前的下载源设置。\n如遇到问题,你可以点击右上角帮助按钮进行求助。
modpack.wizard.step.initialization.warning=在制作整合包前,请你确认你选择的实例可以正常启动,\n并保证你的 Minecraft 是正式版而非快照,\n而且不应当将不允许非官方途径传播的模组、资源 (纹理) 包等纳入整合包。\n整合包会保存你目前的下载源设置。\n如遇到问题,你可以点击右上角帮助按钮进行求助。
modpack.wizard.step.initialization.server=点击此处查看有关服务器自动更新整合包的制作教程
modrinth.category.adventure=冒险
modrinth.category.atmosphere=氛围
modrinth.category.audio=声音
modrinth.category.babric=Babric
modrinth.category.blocks=方块
modrinth.category.bloom=泛光
modrinth.category.bta-babric=BTA (Babric)
modrinth.category.bukkit=Bukkit
modrinth.category.bungeecord=BungeeCord
modrinth.category.canvas=Canvas
modrinth.category.cartoon=卡通
modrinth.category.challenging=高难度
modrinth.category.colored-lighting=彩色光照
modrinth.category.core-shaders=核心着色器
modrinth.category.combat=战斗
modrinth.category.core-shaders=核心着色器
modrinth.category.cursed=Cursed
modrinth.category.datapack=数据包
modrinth.category.decoration=装饰
modrinth.category.economy=经济
modrinth.category.entities=实体
@@ -775,6 +781,7 @@ modrinth.category.environment=环境
modrinth.category.equipment=装备
modrinth.category.fabric=Fabric
modrinth.category.fantasy=幻想
modrinth.category.folia=Folia
modrinth.category.foliage=植被
modrinth.category.fonts=字体
modrinth.category.food=食物
@@ -784,7 +791,9 @@ modrinth.category.gui=GUI
modrinth.category.high=高
modrinth.category.iris=Iris
modrinth.category.items=物品
modrinth.category.java-agent=Java Agent
modrinth.category.kitchen-sink=大杂烩
modrinth.category.legacy-fabric=Legacy Fabric
modrinth.category.library=支持库
modrinth.category.lightweight=轻量
modrinth.category.liteloader=LiteLoader
@@ -802,8 +811,10 @@ modrinth.category.models=模型
modrinth.category.modloader=Modloader
modrinth.category.multiplayer=多人
modrinth.category.neoforge=NeoForge
modrinth.category.nilloader=NilLoader
modrinth.category.optifine=OptiFine
modrinth.category.optimization=优化
modrinth.category.ornithe=Ornithe
modrinth.category.paper=Paper
modrinth.category.path-tracing=路径追踪
modrinth.category.pbr=PBR
@@ -832,8 +843,6 @@ modrinth.category.vanilla-like=类原生
modrinth.category.velocity=Velocity
modrinth.category.waterfall=Waterfall
modrinth.category.worldgen=世界生成
modrinth.category.datapack=数据包
modrinth.category.folia=Folia
mods=模组
mods.add=添加模组
@@ -880,7 +889,7 @@ mods.not_modded=你需要先在“自动安装”页面安装 Forge、NeoForge
mods.restore=回退
mods.url=官方页面
mods.update_modpack_mod.warning=更新整合包中的模组可能导致整合包损坏,使整合包无法正常启动。该操作不可逆,确定要更新吗?
mods.install=安装到当前版本
mods.install=安装到当前实例
mods.save_as=下载到本地文件夹
nbt.entries=%s 个条目
@@ -945,6 +954,7 @@ world.info.player.food_level=饥饿值
world.info.player.game_type=游戏模式
world.info.player.game_type.adventure=冒险
world.info.player.game_type.creative=创造
world.info.player.game_type.hardcore=极限
world.info.player.game_type.spectator=旁观者
world.info.player.game_type.survival=生存
world.info.player.health=生命值
@@ -1032,9 +1042,9 @@ 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_NAME: 实例名称;\n\
\ · $INST_ID: 实例名称;\n\
\ · $INST_DIR: 当前实例运行路径;\n\
\ · $INST_MC_DIR: 当前游戏文件夹路径;\n\
\ · $INST_JAVA: 游戏运行使用的 Java 路径;\n\
\ · $INST_FORGE: 若安装了 Forge,将会存在本环境变量;\n\
@@ -1044,18 +1054,18 @@ settings.advanced.custom_commands.hint=自定义命令被调用时将包含如
\ · $INST_FABRIC: 若安装了 Fabric,将会存在本环境变量;\n\
\ · $INST_QUILT: 若安装了 Quilt,将会存在本环境变量。
settings.advanced.dont_check_game_completeness=不检查游戏完整性
settings.advanced.dont_check_jvm_validity=不检查 JVM 与游戏的兼容性
settings.advanced.dont_check_jvm_validity=不检查 Java 虚拟机与游戏的兼容性
settings.advanced.dont_patch_natives=不尝试自动替换本地库
settings.advanced.environment_variables=环境变量
settings.advanced.game_dir.default=默认 (".minecraft/")
settings.advanced.game_dir.independent=各版本独立 (存放在 ".minecraft/versions/<版本名>/",除 assets、libraries 外)
settings.advanced.game_dir.independent=各实例独立 (存放在 ".minecraft/versions/<实例名>/",除 assets、libraries 外)
settings.advanced.java_permanent_generation_space=内存永久保存区域
settings.advanced.java_permanent_generation_space.prompt=单位 MiB
settings.advanced.jvm=Java 虚拟机设置
settings.advanced.jvm_args=Java 虚拟机参数
settings.advanced.jvm_args.prompt=\ · 若在“Java 虚拟机参数”输入的参数与默认参数相同,则不会添加;\n\
\ · 若在“Java 虚拟机参数”输入任何 GC 参数,默认参数的 G1 参数会被禁用;\n\
\ · 开启下方“不添加默认的 JVM 参数”可在启动游戏时不添加默认参数。
\ · 开启下方“不添加默认的 Java 虚拟机参数”可在启动游戏时不添加默认参数。
settings.advanced.launcher_visibility.close=游戏启动后结束启动器
settings.advanced.launcher_visibility.hide=游戏启动后隐藏启动器
settings.advanced.launcher_visibility.hide_and_reopen=隐藏启动器并在游戏结束后重新打开
@@ -1067,8 +1077,9 @@ settings.advanced.natives_directory=本地库路径 (LWJGL)
settings.advanced.natives_directory.choose=选择本地库路径
settings.advanced.natives_directory.custom=自定义 (由你提供游戏需要的本地库)
settings.advanced.natives_directory.default=默认 (由启动器提供游戏本地库)
settings.advanced.natives_directory.hint=本选项提供给 Apple M1 等未受游戏官方支持的平台来自定义游戏本地库。如果你不知道本选项的含义,请不要修改本选项,否则会导致游戏无法启动!\n\n如果你要修改本选项,你需要保证自定义文件夹下有游戏所需的本地库文件,如 lwjgl.dll (liblwjgl.so)、openal.dll (libopenal.so) 等文件。启动器不会帮你补全缺少的本地库文件!\n\n注意:指定的本地库文件路径建议只包含英文大小写字母、数字和下划线,否则可能会导致启动游戏失败。
settings.advanced.no_jvm_args=不添加默认的 JVM 参数
settings.advanced.natives_directory.default.version_id=<实例名称>
settings.advanced.natives_directory.hint=本选项提供给 Apple Silicon 等未受游戏官方支持的平台来自定义游戏本地库。如果你不知道本选项的含义,请不要修改本选项,否则会导致游戏无法启动!\n\n如果你要修改本选项,你需要保证自定义文件夹下有游戏所需的本地库文件,如 lwjgl.dll (liblwjgl.so)、openal.dll (libopenal.so) 等文件。启动器不会帮你补全缺少的本地库文件!\n\n注意:指定的本地库文件路径建议只包含英文大小写字母、数字和下划线,否则可能会导致启动游戏失败。
settings.advanced.no_jvm_args=不添加默认的 Java 虚拟机参数
settings.advanced.precall_command=游戏启动前执行命令
settings.advanced.precall_command.prompt=将在游戏启动前调用
settings.advanced.process_priority=进程优先级
@@ -1099,7 +1110,7 @@ settings.custom=自定义
settings.game=游戏设置
settings.game.copy_global=复制全局游戏设置
settings.game.copy_global.copy_all=复制全部
settings.game.copy_global.copy_all.confirm=你确定要覆盖当前版本特定游戏设置吗?此操作无法撤销!
settings.game.copy_global.copy_all.confirm=你确定要覆盖当前实例特定游戏设置吗?此操作无法撤销!
settings.game.current=游戏
settings.game.dimension=游戏窗口分辨率
settings.game.exploration=浏览
@@ -1113,9 +1124,9 @@ settings.game.java_directory.invalid=Java 路径不正确
settings.game.java_directory.version=指定 Java 版本
settings.game.java_directory.template=%s (%s)
settings.game.management=管理
settings.game.working_directory=版本隔离 (建议使用模组时选择“各版本独立”。改后需移动存档、模组等相关游戏文件)
settings.game.working_directory=版本隔离 (建议使用模组时选择“各实例独立”。改后需移动存档、模组等相关游戏文件)
settings.game.working_directory.choose=选择运行文件夹
settings.game.working_directory.hint=在“版本隔离”中选择“各版本独立”使当前版本独立存放设置、存档、模组等数据。使用模组时建议启用此选项以避免不同版本模组冲突。修改此选项后需自行移动存档等文件。
settings.game.working_directory.hint=在“版本隔离”中选择“各实例独立”使当前实例独立存放设置、存档、模组等数据。使用模组时建议启用此选项以避免不同实例模组冲突。修改此选项后需自行移动存档等文件。
settings.icon=游戏图标
@@ -1167,13 +1178,13 @@ settings.physical_memory=物理内存大小
settings.show_log=查看日志
settings.tabs.installers=自动安装
settings.take_effect_after_restart=重启后生效
settings.type=版本游戏设置类型
settings.type.global=全局游戏设置 (未启用“版本特定游戏设置”的版本共用此设置)
settings.type=实例游戏设置类型
settings.type.global=全局游戏设置 (未启用“实例特定游戏设置”的实例共用此设置)
settings.type.global.manage=全局游戏设置
settings.type.global.edit=编辑全局游戏设置
settings.type.special.enable=启用版本特定游戏设置 (不影响其他游戏版本)
settings.type.special.edit=编辑版本特定游戏设置
settings.type.special.edit.hint=当前游戏版本“%s”启用了“版本特定游戏设置”,因此本页面选项不对该版本生效。点击链接前往该版本的“游戏设置”页。
settings.type.special.enable=启用实例特定游戏设置 (不影响其他游戏实例)
settings.type.special.edit=编辑实例特定游戏设置
settings.type.special.edit.hint=当前游戏实例“%s”启用了“实例特定游戏设置”,因此本页面选项不对该实例生效。点击链接前往该实例的“游戏设置”页。
sponsor=赞助
sponsor.bmclapi=国内下载源由 BMCLAPI 提供高速下载服务。BMCLAPI 为公益服务,赞助 BMCLAPI 可以帮助作者更好地提供稳定高速的下载服务。[点击此处查阅详细信息]
@@ -1208,13 +1219,15 @@ update.note=开发版与预览版包含更多的功能以及错误修复,但
update.latest=当前版本为最新版本
update.no_browser=无法打开浏览器。网址已经复制到剪贴板,你可以手动粘贴网址打开页面。
update.tooltip=更新
update.preview=提前预览 HMCL 版本
update.preview.tooltip=启用此选项,你将可以提前获取 HMCL 的新版本,以便在正式发布前进行测试。
version=游戏
version.name=游戏版本名称
version.cannot_read=读取游戏版本失败,无法进行自动安装
version.empty=没有游戏版本
version.name=游戏实例名称
version.cannot_read=读取游戏实例失败,无法进行自动安装
version.empty=没有游戏实例
version.empty.add=进入下载页安装游戏
version.empty.launch=没有可启动的游戏。点击“确定”将进入“下载”页面。\n你也可以点击 HMCL 主界面左侧的“下载”按钮安装游戏,或在“版本列表”切换游戏文件夹。
version.empty.launch=没有可启动的游戏。点击“确定”将进入“下载”页面。\n你也可以点击 HMCL 主界面左侧的“下载”按钮安装游戏,或在“实例列表”切换游戏文件夹。
version.empty.hint=没有已安装的游戏。\n你可以切换其他游戏文件夹,或者点击此处进入游戏下载页面。
version.game.old=远古版
version.game.release=正式版
@@ -1223,30 +1236,30 @@ version.game.snapshot=快照
version.game.snapshots=快照
version.launch=启动游戏
version.launch.test=测试游戏
version.switch=切换版本
version.switch=切换实例
version.launch_script=生成启动脚本
version.launch_script.failed=生成启动脚本失败
version.launch_script.save=保存启动脚本
version.launch_script.success=启动脚本已生成完毕:%s
version.manage=版本列表
version.manage=实例列表
version.manage.clean=清理游戏文件夹
version.manage.clean.tooltip=清理“logs”和“crash-reports”文件夹
version.manage.duplicate=复制游戏版本
version.manage.duplicate=复制游戏实例
version.manage.duplicate.duplicate_save=复制存档
version.manage.duplicate.prompt=请输入新游戏名称
version.manage.duplicate.confirm=新的游戏版本将复制该版本文件夹 (".minecraft/versions/<版本名>") 下的文件,并带有独立的运行文件夹和设置。
version.manage.manage=版本管理
version.manage.manage.title=版本管理 - %1s
version.manage.duplicate.confirm=新的游戏实例将复制该实例文件夹 (".minecraft/versions/<实例名>") 下的文件,并带有独立的运行文件夹和设置。
version.manage.manage=实例管理
version.manage.manage.title=实例管理 - %1s
version.manage.redownload_assets_index=更新游戏资源文件
version.manage.remove=删除该版本
version.manage.remove.confirm=真的要删除版本“%s”吗?你将无法找回被删除的文件!!!
version.manage.remove.confirm.trash=真的要删除版本“%s”吗?你可以在系统的回收站中还原“%s”文件夹来找回该版本。
version.manage.remove.confirm.independent=由于该游戏启用了“(全局/版本特定) 游戏设置 → 版本隔离 → 各版本独立”选项,删除该版本将导致该游戏的存档等数据一同被删除!真的要删除版本“%s”吗?
version.manage.remove=删除该实例
version.manage.remove.confirm=真的要删除实例“%s”吗?你将无法找回被删除的文件!!!
version.manage.remove.confirm.trash=真的要删除实例“%s”吗?你可以在系统的回收站中还原“%s”文件夹来找回该实例。
version.manage.remove.confirm.independent=由于该游戏启用了“(全局/实例特定) 游戏设置 → 版本隔离 → 各实例独立”选项,删除该实例将导致该游戏的存档等数据一同被删除!真的要删除实例“%s”吗?
version.manage.remove_assets=删除所有游戏资源文件
version.manage.remove_libraries=删除所有库文件
version.manage.rename=重命名该版本
version.manage.rename=重命名该实例
version.manage.rename.message=请输入要修改的名称
version.manage.rename.fail=重命名版本失败,可能文件被占用或者名字有特殊字符。
version.manage.rename.fail=重命名实例失败,可能文件被占用或者名字有特殊字符。
version.settings=游戏设置
version.update=更新整合包
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<!DOCTYPE html>
<html lang="zh-CN">
<html lang="%lang%">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
File diff suppressed because it is too large. Load diff
+185 -41
View File
@@ -170,7 +170,7 @@ all-the-mods-6;164;;All the Mods 6;;ATM6
garden-of-glass-questbook-edition;165;;Garden of Glass (Questbook Edition);;
;166;;圣剑传奇;Sword Legendary;
;167;;FTB Presents Direwolf20 1.16;;
team-rustic;168;;Rusty Sink 1.20;;
team-rustic;168;;Rusty Sink 2;;
enigmatica2expertskyblock;169;;Enigmatica 2: Expert Skyblock;;E2ES
;170;;休闲-生存-2021版;Leisure Survival-2021;ls21
hexxit-updated;171;;Hexxit Updated;;
@@ -195,7 +195,7 @@ mineshafts-monsters;189;;矿井与怪物;Mineshafts & Monsters;
crazy-craft-remastered;190;;Crazy Craft Remastered;;
engineers-life-2;191;;Engineer's Life 2;;EL2
hr-new-beginnings-2;192;;HR: New Beginnings 2;;
minecolonies-testpack;193;;模拟殖民地;MineColonies Official;
minecolonies-official;193;;模拟殖民地;MineColonies Official;
tnp-limitless;194;;TNP Limitless;;
tnp-limitless-2;195;;TNP Limitless 2;;
tnp-limitless-3;196;;TNP Limitless 3;;
@@ -251,9 +251,9 @@ fabulously-optimized;248;;难以置信的优化;Fabulously Optimized;FO
better-minecraft-otv-edition;249;;Better Minecraft (OfflineTV Edition);;
evolution-reset;250;;进化:重启;Evolution: Reset;ER
the-nuclear-wasteland;251;;核荒原;The Nuclear Wasteland;
blessed-or-cursed-expedition-to-infinite-force;252;;祝福或诅咒:无限力量之征;Blessed or Cursed: Expedition to Infinite Force;BOC
blessed-or-cursed-expedition-to-infinite-force;252;;祝福或诅咒:无限力量之征;Blessed or Cursed: Expedition to Infinite Force;BoC
;253;;边界生存;Border Survival;BSV
medieval-mc-fabric;255;;Medieval Minecraft;;MMC
medieval-mc-forge-mmc1;255;;Medieval Minecraft;;MMC
heavens-of-sorcery;256;;巫术天堂;Heavens of Sorcery;
herodotus;257;;希罗多德;Herodotus-Authentic Edition:Official;HDS
;258;;重生世界;Rebirth world;RW
@@ -282,7 +282,7 @@ world-of-dragons-ii;282;;World of Dragons II;;
tensura-unleashed;283;;Tensura Unleashed;;
skyopolis-4;284;;Skyopolis 4;;
ftb-oceanblock;286;;FTB OceanBlock;;
tolkiencraft-iii-return-to-middle-earth;287;;TolkienCraft III - Return to Middle-earth;;
tolkiencraft-iii-return-to-middle-earth;287;;托尔金工艺3 - 重返中洲;TolkienCraft III - Return to Middle-earth;TC3
delivery-inc;288;;Delivery Inc.;;
poetica;289;;Poetica;;
divine-journey-2;290;;神圣之旅2;Divine Journey 2;DJ2
@@ -354,7 +354,7 @@ all-the-mods-expert-remastered;355;;All The Mods Expert: Remastered;;
all-the-mods-0;356;;All the Mods 0;;ATM0
all-the-mods-fabric;357;;All the Mods Fabric;;ATMF
the-pixelmon-modpack;358;;The Pixelmon Modpack;;
better-minecraft-skyblock;359;;更好的我的世界:空岛;Better Minecraft Skyblock;
better-mc-skyblock;359;;更好的我的世界空岛;Better MC Skyblock;BMCS
age-of-fate;360;;命运时代;Age of Fate;AOF
minecraft-kingdoms;361;;MC Kingdoms;;
;362;;幻想旅程;Imaginary Journey;
@@ -413,7 +413,6 @@ epoch-runner-formerly-nuclear-beyond-modpack;417;;时代领跑人;Epoch Runner;
;418;;星海征途;The Journey of Star Sea;TJoSS
roguelike-adventures-and-dungeons-2;419;;冒险与地牢2;Roguelike Adventures and Dungeons 2;RAD2
multiskyblock;420;;模块化空岛;MultiSkyBlock;MSB
;421;;人性化;Humanized;H
create-live-3;422;;Create Live 3;;
magnificia;423;;Magnificia;;
;424;;魔法金属-新手向导;ManaMetalMod - WithNewbHelper;
@@ -484,7 +483,7 @@ dimensionhopper;490;;Dimension Hopper:The Fall;;
technology-empty-island;491;;科技空岛;RxanGrben;
greed-the-resource-4-infinity;492;;Greed the Resource 4 - Infinity;;
caveopolis;493;;Caveopolis;;
;494;;硬核生存;HardCraft;HC
;494;;坚毅征途;HardCraft;HC
;495;;怀末韵云;Institutions mz;MZ1
feed-the-factory;496;;Feed the Factory;;FTF
fantasy-realm;497;;幻想领域;Fantasy Realm;
@@ -567,7 +566,6 @@ expert-of-magic-art-world;573;;魔艺世界;Expert of Magic Art World;EOMAW
nuclear-radiation-2;576;;核污染二;nuclear radiation 2;NR2
;577;;白狐铃的奇思妙想;Arctic Fox Ling Fantasy;AFLF
;578;;MineSpace;;MS
;579;;史诗战斗:兵团战争;EPIC Fight Corps War;EFC
;580;;月见清兰的个人优化;TskimiSeiran's Idea;TkSrI
;581;;兔头:真视世界;;
;582;;灾厄战争;;
@@ -584,7 +582,7 @@ the-winter-frontier;591;;冬境边域;The Winter Frontier;TWF
;593;;太阳机械厂;Create Sun;CS
dawn-craft;594;;破晓之界;DawnCraft: Echoes of Legends;DC
aof-presents-skylore;595;;AOF: Skylore;;
keletus-gregpack;596;;可乐兔的格雷整合包;Keletu's GregPack;
keletus-gregpack;596;;可乐兔的格雷整合包;Keletu's GregPack;GtMagic
ftb-skies;597;;FTB Skies;;
tnp-limitless-5;598;;TNP Limitless 5;;
create-back-on-track;599;;Create: Back on Track;;
@@ -614,8 +612,8 @@ eternal-night-modpacks;622;;永夜;Eternal Night;ETN
all-the-mods-9;623;;All the Mods 9;;ATM9
spoornpack;624;;Spoornpack;;
;625;;起源RPG;;ORPG
;626;;钓月织梦;Tsuri No Gatsu;TSNG
;627;;冰河物语;Ice Age Fairy;IAF
;626;;织彩钓月;Oriun Tagayasu;OTSU
;627;;冰河物语;;
hommage;628;;Hommage;;
days-to-craft;629;;Seven Days To Craft;;
emcworld;630;;质能世界;EMCWorld;
@@ -668,7 +666,7 @@ journey-watch-ytz;676;;征途 守望;Journey Watch;JW
;677;;Arcomua Lite 原版整合;Arcomua Lite;AL
incremental-industries;678;;Incremental Industries;;
;679;;海王星计划:重构;NeptunePlan:Reboot;NPR
;680;;中世纪生存日记;Medieval Survival Diary;MSD
;680;;求生日记:荒野;Survival Diary: Wilderness;SWD
a-new-technological-era;681;;A New Technological Era;;ANTE
;682;;超能力之旅;Meet Your Superpower;MYS
musketeer;683;;Musketeer - One for All;;
@@ -692,7 +690,7 @@ enigmatica9;699;;Enigmatica 9;;E9
create-arcane-engineering;701;;机械动力:奥术工程;Create: Arcane Engineering;CAE
chroma-endless-2;702;;Chroma Endless 2;;
techrevolution;703;;TechRevolution;;
cabin;704;;CABIN: Create Above & Beyond In Newer;;CABIN
cabin;704;;Create Above & Beyond In Newer;;CABIN
aoc;705;;All of Create;;
;706;;交错维度3;Among Dimensions 3;AD
gregfactory-sky;707;;GregFactory Sky;;GFS
@@ -735,8 +733,8 @@ life-in-the-village-3;740;;Life in the village 3;;LitV3
;745;;FTB Genesis;;
cook-in-skyblock;746;;天空厨房;Cook in skyland;CiS
;747;;被恐惧支配 1;Dominated by Fear 1;DoF
new-vanilla-modpack;748;;新的原版;New Vanilla;NVA
;749;;群峦救援非官方版;Terrafirma Rescue Unofficial;TFRU
new-vanilla-newhome;748;;新的原版;New Vanilla;NVA
;749;;峦屿梦星群;Terrafirma Rescue Unofficial;TFRU
stoneopolis;750;;Stoneopolis;;
ftb-skies-expert;751;;FTB Skies Expert;;
wmshd-pack-what-mojang-should-have-done;752;;What Mojang Should Have Done;;WMSHD
@@ -744,7 +742,7 @@ wmshd-pack-what-mojang-should-have-done;752;;What Mojang Should Have Done;;WMSHD
;754;;随心之旅;spontaneous journey;
oxmodpack;755;;OxMODPACK 8 +Online;;
gregtech-community-pack-modern;756;;GregTech Community Pack Modern;;GCPM
;757;;锻造大师3;Master Blacksmith3;MB3
;757;;锻造大师4;Master Blacksmith4;MB4
;758;;科技用于探索世界;Technology Exploration World;
;759;;幻梦闲笔;Aetherial Voyage;
fear-the-mist;760;;雾中的恐惧;Fear The Mist;
@@ -764,7 +762,7 @@ infernal-rpg;771;;Infernal Origins;;
;774;;AIR for JAVA;;AFJ
;775;;Create Extra;;
frs-optimisation-for-survival;776;;Fr的生存优化;Fr's Optimisation for Survival;FROS
;777;;Exile Magic Constructor;;EMC
exile-magic-constructor;777;;Exile Magic Constructor;;EMC
;778;;Landscapes Reimagined Genesis;;
al-nl;779;;冒险生活 - 新生活;Adventure Life - New Life;AL-NL
harvista;780;;拾穗;Harvista;
@@ -819,19 +817,19 @@ all-the-mods-9-to-the-sky;828;;All The Mod 9 - To The Sky;;ATM9S
fallenpetals;830;;落英;FallenPetals;FP
dungeon-heroes;831;;Dungeon Heroes (RPG Series);;
play-as-dragon-gothic-edition;832;;Play as Dragon: Gothic Edition;;
skyblock-burgeria;833;;空岛汉堡店;;
skyblock-burgeria;833;;空岛汉堡店;Skyblock Burgeria;
crafting-craft-2;834;;合成工艺2;Crafting Craft 2;
;835;;僵尸入侵100天;Zombie Invade 100 Days;ZI100D
compact-world-expert;836;;Compact World Expert;;CWE
a-fragment-of-peace;837;;宁然一隅;A Fragment of Peace;AFoP
;837;;宁然一隅;A Fragment of Peace;AFoP
easy-create-modpack;838;;Easy Create;;
;839;;流线鱼概念;Fish Spi Rally;FSRMP
meatballcraft;840;;肉丸工艺,次元提升;MeatballCraft, Dimensional Ascension;
meatballcraft;840;;肉丸工艺,次元飞升;MeatballCraft, Dimensional Ascension;MBC
seaopolis-submerged;841;;海之城: 潜没水中;Seaopolis: Submerged;
;842;;空中厕所;PoopSky;
compact-sky;843;;收缩空岛;Compact Sky;
back-to-back;844;;背靠背;Back to Back;BTB
adventure-exploration-part2;845;;冒险与探索;Adventure & Exploration;AnE
ane2;845;;冒险与探索;Adventure & Exploration;AnE
;846;;复兴;Renaissance;
live-like-a-castaway;847;;木筏求生2;Raftcraft2;RC2
mermaid-legend;848;;人鱼传说;Mermaid legend;
@@ -847,7 +845,6 @@ create-prepare-to-dye;856;;Create Prepare to Dye;;
create-leisurely-delight;858;;机械动力:悠然乐事;Create Delight;CD
;859;;蔚蓝悠悠;Azure Leisurely;AL
infinityevolved-reloaded;860;;Infinity Evolved: Reloaded;;
;861;;空中厕所:生产线;Poopsky:Assembly Line;PAL
;862;;佛罗伦萨迷思;Fantasy in Florence;FIF
craftoria;863;;Craftoria;;
mechanic-craft;864;;MechanicCraft;;
@@ -878,7 +875,7 @@ create-stellar;888;;Create Stellar;;
monifactory;889;;Monifactory;;
create-factory-builder;890;;Create: Factory Builder;;
;891;;群峦传说:宝宝快乐版;TerraFirma: Baby Happy Edition;TFBH
;892;;阶段: 残骸;Phase: the Debris;
;892;;阶段: 残骸;Phase: the Debris;PTD
;893;;AE管道;AE Pipes;APE
skyt-2;894;;SkyT 2;;
stagecraft;895;;StageCraft;;
@@ -909,7 +906,7 @@ strictly-medieval-3-forge;917;;Strictly Medival 3;;
easy-to-ascension;920;;易如飞升;Easy to Ascension;
;921;;幽匿末日;The Last Day of Sculk;TLDS
;922;;交错空岛;Crossisland;CrI
;923;;机械动力:魔法乐事;Create Magic's Delight;CRMD
;923;;机动工程:刀剑与魔法;Mechanical Engineering: SlashBlade and Magic;CRMD
minetech-evolution;924;;科技进化;Minetech Evolution;MTE
gregified-sky-edition;925;;Gregified: Sky Edition;;
;926;;原版扩展;Additonal Vanilla;AV
@@ -917,14 +914,14 @@ create-on-a-potato;927;;Create on a Potato PC: Ultimate;;CPU
;928;;现实主义;realism;RLM
;929;;晋升之路;path of advance;POA
;930;;永无止境:超越常新;Above and Beyond : Refresh;CABR
cosmic-frontiers;931;;Cosmic Frontiers;;
cosmic-frontiers;931;;星河边疆;Cosmic Frontiers;CF
integrated-minecraft;932;;Integrated MC;;
;933;;Rising Legends;;
;934;;城乡之旅;Travel Township;TT
;934;;城乡之旅;Harvest's Journey;HJ
;935;;龙鸣牢大;FarmerKobeBryant;FKB
setgamedifficulty-reika;936;;SetGameDifficulty Reika;;
epic-journey-gtceu;937;;Epic Journey GTCEu;;
;938;;飞渡群峦;TerraFirmaCraft:Leap The Top;TFC:LTT
terrafirmacraft-leap-the-top;938;;飞渡群峦;TerraFirmaCraft:Leap The Top;TFC:LTT
gregtech-skybound;939;;Gregtech: Skybound;;
simple-tfc;940;;简单群峦;SimpleTFC;
ftb-presents-direwolf20-s14;941;;FTB Presents Direwolf20 1.21;;
@@ -948,10 +945,10 @@ gregtania6-skyblock;959;;Gregtania6 Skyblock;;
harmonious-engineering;960;;Harmonious Engineering;;
valley-of-farming-and-ranching;961;;农牧物语;Valley of Farming and Ranching;
;962;;机械动力:火车;Create Train;
;963;;理想国冒险之旅;;AOIC
the-old-era-of-the-republic-fot-yifei;963;;理想国冒险之旅;;AOIC
;964;;生欲:求生2;Vivere The Zombie Apocalypse-II;VZA2
;965;;起源-世界;OriginCraft Pulses;
;966;;Legacies;;
legacies-mc;966;;Legacies;;
the-legend-of-2900;967;;海上机械师;The Legend Of 2900;TLOU
mirasites-100-days;968;;畸变:蛊之奇境;Mirasites-BrokenMemories;MBM
;969;;末日余晖:独自一人;;MRYH
@@ -970,7 +967,7 @@ venoms-craft;981;;Venom's Craft;;
;982;;慢生活冒险;;
;983;;多元工艺:绘镇曲;Painted Town Melody;PTM
;984;;遗忘之海;Leisurely Life;
;985;;幻想国度;F_Land;
;985;;幻想国度;Fancy_Land;
;986;;群峦传说:重制;TerraFirmaCraft Remake;TFCRe
;987;;未来;;
;988;;起源生物—崛起;;
@@ -988,12 +985,12 @@ industrial-machines;1000;;Industrial Machines;;
auto-terrafirmacraft-tfc-create;1001;;Auto-TerraFirmaCraft (TFC + Create);;ATFC
;1002;;时间之书:星的日记;The Book of Time: A Star's Journal;TASL
;1003;;特摄世界;Tokusatsu World;TW
journey-of-reincarnation;1004;;转世之旅;Journey of Reincarnation;
journey-of-reincarnation;1004;;转世之旅;Tensura: Journey of Reincarnation;
;1005;;冒险与休闲;Adventure and Leisure;AL
enigmatica10;1006;;Enigmatica 10;;E10
mc-chocolate-edition;1007;;The Chocolate Edition;;
mc-chocolate-edition;1007;;Chocolate Edition Minecraft;;
civilization-l;1008;;Civilization-L;;
;1009;;群峦:降临;TerraFirma:Advent;TFA
terrafirma-advent;1009;;群峦:降临;TerraFirma:Advent;TFA
valhelsia-7;1010;;Valhelsia 7;;
mechanical-mastery-plus;1011;;Mechanical Mastery Plus;;
ashes-to-ashes;1012;;尘归尘;Ashes To Ashes;ATA
@@ -1001,23 +998,23 @@ ashes-to-ashes;1012;;尘归尘;Ashes To Ashes;ATA
create-silence-and-prosperity;1014;;机械动力:寂静与繁荣;Create Silence and Prosperity;CSP
mif;1015;;MI:Foundation;;MIF
c2mse2;1016;;Create 2 Mekanism: Sky Edition 2;;C2MSE2
;1017;;Tsuri No Gatsu 5 - FDCraft Version;;TSNG5-FDC
;1017;;耕云钓月;Kumo O Tagayasu;KOTS
;1018;;无限战争4;Infinity War4;INF4
;1019;;群峦传说:工业长路;;
;1020;;自然冒险 初生;Nature Adventure Newborn;NAB
;1021;;羽舲的基础优化;Hanekmio's Basis Optimization;
;1020;;自然冒险 新生;Nature Adventure Newborn;NAB
hmbo;1021;;羽舲的基础优化;Hanekmio's Basis Optimization;
create-star-valley;1022;;Create: Gears of History;;
;1023;;阿尔法计划;AlphaPlan;AP
spell-dimension;1024;;咒次元;Spell Dimension;SD
skyfactory-5;1025;;天空工厂 5;SkyFactory 5;SF5
;1026;;破劫之刃;Break Disaster;
reminiscent-create;1027;;Reminiscent Create;;
techsert;1028;;Techsert;;TH
techsert;1028;;匿踪之城;Techsert;TH
prehistoric-world-dinosaurs-adventure;1029;;Prehistoric World - Dinosaurs & Adventure;;
terminal;1030;;终末;Terminal;
;1031;;异次元水晶 3;Isolated Crystal 3;
isolated-crystal-3;1031;;异次元水晶 3;Isolated Crystal 3;
;1032;;机械动力:无限总是小于零;Create:Infinity Always Smaller Than Zero;CIASZ
;1033;;踪灭I-开端;;
;1033;;踪灭I-起源;;
;1034;;踪灭II;;
rabbits-dawn-craft;1035;;某兔子的破晓之界;A Certain Rabbit's DawnCraft - Dawn of the Deep Soul;RDC
;1036;;铁砧天空;;ASKY
@@ -1027,7 +1024,7 @@ the-adventure-of-valkyriens;1038;;瓦尔基里大冒险;The Adventure of Valkyri
;1040;;群峦传说:天才版;;
compression;1041;;Compression;;
compact-sky-easy;1042;;Compact Sky: Easy;;CSE
;1043;;丰收与探索;;
;1043;;丰收与探索;Harvest and Exploration;
;1044;;脆骨症:黯光;No Flesh Within Chest-DIM;NFWC-DIM
;1045;;小雷的优化冒险;;
cobblemon-eternal-edition;1046;;Cobblemon Eternal;;
@@ -1035,3 +1032,150 @@ cobblemon-eternal-edition;1046;;Cobblemon Eternal;;
gregtech-expert;1048;;GregTech Expert;;
;1049;;Beta Horizons;;
minecraft-legendary-edition;1050;;Legendary Edition;;
;1051;;Origenceal LPackage;;OLP
;1052;;我的世界:未闻的故事;;mtus
;1053;;Versatile;;
;1054;;勇者之章 Ⅲ;Chapter of Yuusha Ⅲ;CY3
forge-frontier;1055;;Create - Forge Frontier;;
create-workshop-uwu;1056;;Create: Workshop UwU Edition;;
;1057;;古钠重铸;Oldium Optimized;OO
;1058;;越寰;Leaping across the world;LTW
ftb-oceanblock-2;1059;;FTB OceanBlock 2;;
;1060;;伊甸空天2;Eden Aerospace 2;EAS2
create-infinity-mechanism;1061;;机械动力:无限构件;Create:Infinity Mechanism;CIM
beyond-depth;1062;;Beyond Depth;;
;1063;;枪械交界地;TACZ Amid Crucible Zone;
;1064;;真幻世界;Realfantacy World;R.F.
minenufactory;1065;;创世工厂;Minenufactory;MF
craft-to-exile-2;1066;;放逐之路2;Craft to Exile 2 (VR Support);CTE2
;1067;;龙境III:菌土重来;Dragon Odyssey:Return of the Fungal Earth;DO3
the-culinary-journey;1068;;美食的旅途;The Culinary Journey;TCJ
;1069;;缥缈方舟;;PMFZ
;1070;;东方匠魂传;Touhou Tinker Fantasy;TTF
;1071;;亵渎;;MYBL
techopolis-3;1072;;Techopolis 3;;
sky1234;1074;;sky1234;;
star-technology;1075;;Star Technology;;
;1076;;Hyper World;;HW
;1077;;妖月的魔法金属整合包;yaoyaoDream's ManaMetalMod Modpack;YMM
techcraft-severwinter;1078;;科技工艺:严冬;TechCraft: SevereWinter;TCSW
randblock2-winterize;1079;;随机空岛 2:银装素裹;RandBlock2:Winterize;
create-the-brass-concerto;1080;;机械动力:黄铜协奏曲;Create: The Brass Concerto;CBC
explorers-eve;1081;;Explorer's Eve;;
all-the-magic-arcana;1082;;All the Magic :Arcana;;ATMAr
;1083;;创想新世界;Inspired Creations: New World;ICNW
farming-crossing-5-made-to-order;1084;;农业森友会 5;Farming Crossing 5: Made to Order!;
;1085;;Ben10 Craft;;BEN10
;1086;;渺小的世界;Small world;
mierno;1087;;迷厄路;Mierno;
;1088;;最后那些天;Those last day;
;1089;;泠月狐基础整合;LunarFox;
roguelike-adventures-and-dungeons-3;1090;;冒险与地牢3;Roguelike Adventures and Dungeons 3;RAD3
;1091;;羽舲界;Hanekmio Instance;HMI
;1092;;玄理2:洗剪版;EnigTech 2 - Dishwasher's Cut;ET2DC
wheelchair-gregtech;1093;;Wheelchair Gregtech;;
egged-up;1094;;Egged Up;;
;1095;;香草纪元:食旅纪行;VanillaEra: FaresChron;
;1096;;愚者;The Fool;TF
;1097;;时间之书2:星梦指南;BookofTime II Stardream Compass;BKSC
;1098;;群峦之上:无垠伊土;EndlessFirma;EnF
;1099;;血月低语:暗夜惊魂;Bloodmoon's Whisper;BW
;1100;;MC饭;Delicious in Minecraft;DIM
;1101;;美味的甜点总是有毒;;
delight-desert-chef;1102;;乐事:沙漠厨师;Delight: Desert Chef;DDC
;1103;;异界随行诗;Otherworld Traveling Poems;
;1104;;无边荒漠;;
;1105;;空中厕所2;PoopSky2;
fear-nightfall;1106;;Fear Nightfall;;
homestead-cozy;1107;;Homestead - A Cozy Survival Experience;;HD
madness-of-the-skies;1108;;Madness of the skies;;
;1109;;魔之逆鳞;Nemesis of Demons;NOD
emc-and-fe-plus2;1110;;EMC & FE ++;;E&F
;1111;;云之谷;CloudValley;
bm-exosphere;1112;;BM: Exosphere;;BME
;1113;;锻造大师:侠之器;Master Blacksmith:Chivalrous blade;MB:CB
;1114;;自然;Nature;NA
;1115;;农场物语;FarmingTales;FT
optimaxcraft;1116;;OptiMaxCraft;;OMC
;1117;;决战黎明;Decisive Battle at Dawn;DBAD
floaty-creatoria;1118;;天工浮生;Floaty Creatoria;
;1119;;简约生电优化;Simplicity Survival Optimization;SSO
;1120;;星辰之下;Under the Stars;UtS
madness-of-the-skies-2;1121;;Madness of the Skies 2;;
raspberry-flavoured;1122;;Raspberry Flavoured;;RF
skillet-man;1123;;平底锅侠;Skillet Man;
;1124;;格雷科技:新征程;GregTech Odyssey;GTO
;1125;;无中生无尽;Ex Nihilo Ad Avaritia;ENAA
;1126;;Undertale;;
create-creative-and-beyond;1127;;机械动力:创造与超越;Create Creative and Beyond;CCB
create-delight-remake;1128;;机械动力:齿轮盛宴;Create:Delight Remake;CDR
ftb-skies-2;1129;;FTB Skies 2;;
;1130;;星辰时代:科技魔法;Stellar Era: Technomagic;SETM
aircrashed-engineer;1131;;坠机工程师;Aircrashed Engineer;ACE
project-tfcreate;1132;;Project: TFCreate;;
;1133;;落幕曲;;
;1134;;超大陆:勇气;Supercontinent:Pluck;SUPL
create-chronicles-the-endventure;1135;;Create Chronicles: The Endventure;;
life-in-the-village-4;1136;;Life in the village 4;;LITV4
real-island-2-modular-craft;1137;;真实空岛2:模块化之旅;Real Island 2 - Modular Craft;RI2
;1138;;奥术咖啡馆;;
unyielding;1139;;Unyielding;;
;1140;;剑与王国;;SNK
the-fungal-infection-coop;1141;;The Fungal Infection | Co-Op Base Defense;;
mc-eternal-2;1142;;永恒的MC 2;MC Eternal 2;MCE2
solo-leveling-reawakening;1143;;Solo Leveling - Reawakening;;
create-ultimate-selection;1144;;Create: Ultimate Selection - QUESTS NOW!;;
;1145;;元素觉醒;Elemental Awakening;
endless-horror-the-ultimate-horror-modpack;1146;;Endless Horror - The ULTIMATE Horror Experience;;
;1147;;锻造之旅;;
picky;1148;;Picky;;
resource-factory;1149;;资源工厂;Resource Factory;
stacia-2-expert;1150;;Stacia 2 Expert;;S2E
;1151;;田园乐事;;
;1152;;世界之旅;Journey of the world;JOTW
;1153;;清新优化;Fresh optimization;FRO
;1154;;遗世之匠;Touhou:The Forgotten Swordsmith;
;1155;;千禧:蝉鸣之时;;
skyrealm-descent;1157;;Skyrealm: Descent;;
;1158;;远征:以太利亚;Expedition: Ætheria;
;1159;;快速优化;Rapid Optimization;RO
liminal-industries;1160;;阈限工业;Liminal Industries;
;1161;;史诗冒险;;EA
;1162;;根自日常;ROOTINE;
blue-archive-x-mineraft;1163;;我的世界x蔚蓝档案;BlueArchive x Minecraft;BACraft
;1164;;Fresh & Smooth;;
;1165;;机动重启工程:风之旅;The Caravan of Winds;TCW
;1166;;Furry Fandom Club Boss Rush Official Offline;;FFCBR
immersive-ultra;1167;;极致沉浸;Immersive Ultra;
;1168;;Polymania;;
survivearchive;1169;;SurviveArchive - A Blue Archive modpack;;
beloong;1170;;化龍;BeLoong;
;1171;;畅游自然;;SiF
;1172;;退休工艺;Retirement Craft;RmC
;1173;;随机枪械乱斗;NimShade's Random Gunfight;NRG
;1174;;雪狐的基础整合;SF Integrated Modpack;SFI
;1175;;硬核惊变;Hardcore Surprise;HS
society-sunlit-valley;1176;;Society: Sunlit Valley;;
ciscos-fantasy-medieval-rpg-dragonfyre;1177;;Cisco's Fantasy Medieval RPG [Dragonfyre];;
all-the-mods-10-sky;1178;;All the Mods 10: To the Sky;;ATM10S
;1179;;谐伴匠途;;
the-cursed-wanderer-reborn;1180;;咒游诸界:重生;The Cursed Wanderer: Reborn;TCWR
;1181;;Turbo Vulkan;;TuVk
uls-zsurvival-craft;1182;;Z-Liminex;;
;1183;;MITE 重生 3;MITE Reborn 3;MR
reclamation-reclaim-the-world;1184;;Reclamation - Reclaim the World!;;
;1185;;寰宇地球;Earthworld;EW
pokehaan-craft-2;1186;;Pokehaan Craft 2;;
project-nope-zone;1187;;Project Nope Zone;;PNZ
all-the-simple-zero;1188;;一切简易;All the Simple;ATS
;1189;;匠战妖域;Tinkers' Warfare Demon Realm;twdr
;1190;;空想生存;;
;1191;;东方起源鉴;Touhou Origins Annals;TOA
realm-of-destiny;1192;;生命之境;Realm of Destiny;ROD
;1193;;奇妙的世界;Special World;
;1194;;毁灭;DESTRUCTION;DES
pvzw;1195;;植物大战僵尸:世界;Plants VS Zombies : World;PVZW
;1196;;农场物语Forge版;FarmingTales Forge;FT-WT
new-century-adventure;1197;;新世纪之险;New Century Adventure;NCA
repalmon;1198;;Re帕鲁梦;;RPLM
structural-ingenuity;1199;;结构型奇思妙想;Structural Ingenuity;
@@ -4007,6 +4007,17 @@
"size": 27971214
}
}
},
"software-renderer-loader": {
"name": "org.glavo:llvmpipe-loader:1.0",
"downloads": {
"artifact": {
"path": "org/glavo/llvmpipe-loader/1.0/llvmpipe-loader-1.0.jar",
"url": "https://repo1.maven.org/maven2/org/glavo/llvmpipe-loader/1.0/llvmpipe-loader-1.0.jar",
"sha1": "ff255415e5c4b2a18970da0a8e552b557ca013ae",
"size": 12964773
}
}
}
},
"windows-x86": {
@@ -71,15 +71,14 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider {
pair("http://files.minecraftforge.net/maven", apiRoot + "/maven"),
pair("https://files.minecraftforge.net/maven", apiRoot + "/maven"),
pair("https://maven.minecraftforge.net", apiRoot + "/maven"),
pair("https://maven.neoforged.net/releases/net/neoforged/forge", apiRoot + "/maven/net/neoforged/forge"),
pair("https://maven.neoforged.net/releases/net/neoforged/neoforge", apiRoot + "/maven/net/neoforged/neoforge"),
pair("https://maven.neoforged.net/releases/", apiRoot + "/maven/"),
pair("http://dl.liteloader.com/versions/versions.json", apiRoot + "/maven/com/mumfrey/liteloader/versions.json"),
pair("http://dl.liteloader.com/versions", apiRoot + "/maven"),
pair("https://meta.fabricmc.net", apiRoot + "/fabric-meta"),
pair("https://maven.fabricmc.net", apiRoot + "/maven"),
pair("https://authlib-injector.yushi.moe", apiRoot + "/mirrors/authlib-injector"),
pair("https://repo1.maven.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"),
pair("https://zkitefly.github.io/unlisted-versions-of-minecraft", "https://vip.123pan.cn/1821946486/unlisted-versions-of-minecraft")
pair("https://zkitefly.github.io/unlisted-versions-of-minecraft", "https://alist.8mi.tech/d/mirror/unlisted-versions-of-minecraft/Auto")
);
}
@@ -24,6 +24,7 @@ import org.jackhuang.hmcl.game.ReleaseType;
import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Immutable;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
import java.time.Instant;
import java.util.List;
@@ -53,10 +54,16 @@ public final class GameRemoteVersion extends RemoteVersion {
@Override
public int compareTo(RemoteVersion o) {
if (!(o instanceof GameRemoteVersion))
if (!(o instanceof GameRemoteVersion)) {
return 0;
}
return o.getReleaseDate().compareTo(getReleaseDate());
int dateCompare = o.getReleaseDate().compareTo(getReleaseDate());
if (dateCompare != 0) {
return dateCompare;
}
return GameVersionNumber.compare(o.getSelfVersion(), getSelfVersion());
}
private static Type getReleaseType(ReleaseType type) {
@@ -169,7 +169,7 @@ public class DefaultLauncher extends Launcher {
}
if (OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS)
res.addDefault("-Duser.home=", options.getGameDir().getParent());
res.addDefault("-Duser.home=", options.getGameDir().getAbsoluteFile().getParent());
Proxy.Type proxyType = options.getProxyType();
if (proxyType == null) {
@@ -132,7 +132,7 @@ public class Datapack {
try {
PackMcMeta pack = JsonUtils.fromNonNullJson(FileUtils.readText(mcmeta), PackMcMeta.class);
Platform.runLater(() -> info.add(new Pack(path, FileUtils.getNameWithoutExtension(path), pack.getPackInfo().getDescription(), this)));
} catch (IOException | JsonParseException e) {
} catch (Exception e) {
LOG.warning("Failed to read datapack " + path, e);
}
} else {
@@ -144,7 +144,7 @@ public class Datapack {
public void loadFromDir() {
try {
loadFromDir(path);
} catch (IOException e) {
} catch (Exception e) {
LOG.warning("Failed to read datapacks " + path, e);
}
}
@@ -302,11 +302,13 @@ public class RemoteMod {
public FileDownloadTask.IntegrityCheck getIntegrityCheck() {
if (hashes.containsKey("md5")) {
return new FileDownloadTask.IntegrityCheck("MD5", hashes.get("sha1"));
return new FileDownloadTask.IntegrityCheck("MD5", hashes.get("md5"));
} else if (hashes.containsKey("sha1")) {
return new FileDownloadTask.IntegrityCheck("SHA-1", hashes.get("sha1"));
} else if (hashes.containsKey("sha256")) {
return new FileDownloadTask.IntegrityCheck("SHA-256", hashes.get("sha256"));
} else if (hashes.containsKey("sha512")) {
return new FileDownloadTask.IntegrityCheck("SHA-256", hashes.get("sha1"));
return new FileDownloadTask.IntegrityCheck("SHA-512", hashes.get("sha512"));
} else {
return null;
}
@@ -26,6 +26,7 @@ import org.jackhuang.hmcl.util.Pair;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.io.HttpRequest;
import org.jackhuang.hmcl.util.io.JarUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jetbrains.annotations.Nullable;
import java.io.ByteArrayOutputStream;
@@ -105,18 +106,19 @@ public final class CurseForgeRemoteModRepository implements RemoteModRepository
if (category != null && category.getSelf() instanceof CurseAddon.Category) {
categoryId = ((CurseAddon.Category) category.getSelf()).getId();
}
Response<List<CurseAddon>> response = HttpRequest.GET(PREFIX + "/v1/mods/search",
pair("gameId", "432"),
pair("classId", Integer.toString(section)),
pair("categoryId", Integer.toString(categoryId)),
pair("gameVersion", gameVersion),
pair("searchFilter", searchFilter),
pair("sortField", Integer.toString(toModsSearchSortField(sortType))),
pair("sortOrder", toSortOrder(sortOrder)),
pair("index", Integer.toString(pageOffset * pageSize)),
pair("pageSize", Integer.toString(pageSize)))
.header("X-API-KEY", apiKey)
.getJson(Response.typeOf(listTypeOf(CurseAddon.class)));
Map<String, String> query = new LinkedHashMap<>();
query.put("gameId", "432");
query.put("classId", Integer.toString(section));
if (categoryId != 0)
query.put("categoryId", Integer.toString(categoryId));
query.put("gameVersion", gameVersion);
query.put("searchFilter", searchFilter);
query.put("sortField", Integer.toString(toModsSearchSortField(sortType)));
query.put("sortOrder", toSortOrder(sortOrder));
query.put("index", Integer.toString(pageOffset * pageSize));
query.put("pageSize", Integer.toString(pageSize));
Response<List<CurseAddon>> response = HttpRequest.GET(NetworkUtils.withQuery(PREFIX + "/v1/mods/search", query)).header("X-API-KEY", apiKey).getJson(Response.typeOf(listTypeOf(CurseAddon.class)));
if (searchFilter.isEmpty()) {
return new SearchResult(response.getData().stream().map(CurseAddon::toMod), calculateTotalPages(response, pageSize));
}
@@ -231,7 +231,7 @@ public class CacheRepository {
String url = conn.getURL().toString();
String lastModified = conn.getHeaderField("Last-Modified");
CacheResult cacheResult = cacheSupplier.get();
ETagItem eTagItem = new ETagItem(url, eTag, cacheResult.hash, Files.getLastModifiedTime(cacheResult.cachedFile).toMillis(), lastModified);
ETagItem eTagItem = new ETagItem(url, eTag, cacheResult.hash, Files.getLastModifiedTime(cacheResult.cachedFile).toMillis(), lastModified, 0L);
Lock writeLock = lock.writeLock();
writeLock.lock();
try {
@@ -325,19 +325,24 @@ public class CacheRepository {
@SerializedName("remote")
private final String remoteLastModified;
// The `expires` field is not used in HMCL 3.6.x, but will be used in HMCL 3.7.x.
// We backported this field to 3.6.x to avoid breaking the etag.json file created by newer HMCL versions.
private final long expires;
/**
* For Gson.
*/
public ETagItem() {
this(null, null, null, 0, null);
this(null, null, null, 0, null, 0L);
}
public ETagItem(String url, String eTag, String hash, long localLastModified, String remoteLastModified) {
public ETagItem(String url, String eTag, String hash, long localLastModified, String remoteLastModified, long expires) {
this.url = url;
this.eTag = eTag;
this.hash = hash;
this.localLastModified = localLastModified;
this.remoteLastModified = remoteLastModified;
this.expires = expires;
}
public int compareTo(ETagItem other) {
@@ -361,12 +366,13 @@ public class CacheRepository {
Objects.equals(url, eTagItem.url) &&
Objects.equals(eTag, eTagItem.eTag) &&
Objects.equals(hash, eTagItem.hash) &&
Objects.equals(remoteLastModified, eTagItem.remoteLastModified);
Objects.equals(remoteLastModified, eTagItem.remoteLastModified) &&
expires == eTagItem.expires;
}
@Override
public int hashCode() {
return Objects.hash(url, eTag, hash, localLastModified, remoteLastModified);
return Objects.hash(url, eTag, hash, localLastModified, remoteLastModified, expires);
}
}
@@ -48,9 +48,10 @@ public final class Lang {
/**
* Construct a mutable map by given key-value pairs.
*
* @param pairs entries in the new map
* @param <K> the type of keys
* @param <V> the type of values
* @param <K> the type of keys
* @param <V> the type of values
* @return the map which contains data in {@code pairs}.
*/
@SafeVarargs
@@ -60,9 +61,10 @@ public final class Lang {
/**
* Construct a mutable map by given key-value pairs.
*
* @param pairs entries in the new map
* @param <K> the type of keys
* @param <V> the type of values
* @param <K> the type of keys
* @param <V> the type of values
* @return the map which contains data in {@code pairs}.
*/
public static <K, V> Map<K, V> mapOf(Iterable<Pair<K, V>> pairs) {
@@ -122,9 +124,10 @@ public final class Lang {
/**
* Cast {@code obj} to V dynamically.
* @param obj the object reference to be cast.
*
* @param obj the object reference to be cast.
* @param clazz the class reference of {@code V}.
* @param <V> the type that {@code obj} is being cast to.
* @param <V> the type that {@code obj} is being cast to.
* @return {@code obj} in the type of {@code V}.
*/
public static <V> Optional<V> tryCast(Object obj, Class<V> clazz) {
@@ -154,8 +157,8 @@ public final class Lang {
/**
* Join two collections into one list.
*
* @param a one collection, to be joined.
* @param b another collection to be joined.
* @param a one collection, to be joined.
* @param b another collection to be joined.
* @param <T> the super type of elements in {@code a} and {@code b}
* @return the joint collection
*/
@@ -172,6 +175,16 @@ public final class Lang {
return list == null ? null : list.isEmpty() ? null : new ArrayList<>(list);
}
public static <T> int indexWhere(List<T> list, Predicate<T> predicate) {
int idx = 0;
for (T value : list) {
if (predicate.test(value))
return idx;
idx++;
}
return -1;
}
public static void executeDelayed(Runnable runnable, TimeUnit timeUnit, long timeout, boolean isDaemon) {
thread(() -> {
try {
@@ -185,6 +198,7 @@ public final class Lang {
/**
* Start a thread invoking {@code runnable} immediately.
*
* @param runnable code to run.
* @return the reference of the started thread
*/
@@ -194,8 +208,9 @@ public final class Lang {
/**
* Start a thread invoking {@code runnable} immediately.
*
* @param runnable code to run
* @param name the name of thread
* @param name the name of thread
* @return the reference of the started thread
*/
public static Thread thread(Runnable runnable, String name) {
@@ -204,8 +219,9 @@ public final class Lang {
/**
* Start a thread invoking {@code runnable} immediately.
*
* @param runnable code to run
* @param name the name of thread
* @param name the name of thread
* @param isDaemon true if thread will be terminated when only daemon threads are running.
* @return the reference of the started thread
*/
@@ -258,7 +274,8 @@ public final class Lang {
/**
* Find the first non-null reference in given list.
* @param t nullable references list.
*
* @param t nullable references list.
* @param <T> the type of nullable references
* @return the first non-null reference.
*/
@@ -1,122 +0,0 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2021 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.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.jar.JarOutputStream;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* @author Glavo
*/
public final class Pack200Utils {
private Pack200Utils() {
}
private static final String[] IMPL_NAMES = {
"java.util.jar.Pack200",
"org.glavo.pack200.Pack200",
"io.pack200.Pack200"
};
private static final MethodHandle newUnpackerHandle;
private static final MethodHandle unpackHandle;
private static final MethodHandle unpackFileHandle;
static {
Class<?> pack200Class = null;
Class<?> unpackerClass = null;
for (String implName : IMPL_NAMES) {
try {
pack200Class = Class.forName(implName);
unpackerClass = Class.forName(implName + "$Unpacker");
break;
} catch (ClassNotFoundException ignored) {
}
}
if (pack200Class == null) {
LOG.warning("Pack200 not found");
newUnpackerHandle = null;
unpackHandle = null;
unpackFileHandle = null;
} else {
final MethodHandles.Lookup lookup = MethodHandles.publicLookup();
MethodHandle newUnpacker = null;
MethodHandle unpack = null;
MethodHandle unpackFile = null;
try {
newUnpacker = lookup.findStatic(pack200Class, "newUnpacker", MethodType.methodType(unpackerClass));
unpack = lookup.findVirtual(unpackerClass, "unpack", MethodType.methodType(void.class, InputStream.class, JarOutputStream.class));
unpackFile = lookup.findVirtual(unpackerClass, "unpack", MethodType.methodType(void.class, File.class, JarOutputStream.class));
} catch (Throwable e) {
LOG.warning("Failed to find pack200 methods", e);
}
if (newUnpacker != null) {
newUnpackerHandle = newUnpacker;
unpackHandle = unpack;
unpackFileHandle = unpackFile;
} else {
newUnpackerHandle = null;
unpackHandle = null;
unpackFileHandle = null;
}
}
}
public static boolean isSupported() {
return newUnpackerHandle != null;
}
public static void unpack(InputStream in, JarOutputStream out) throws IOException {
if (newUnpackerHandle == null) {
throw new UnsupportedOperationException("Pack200");
}
try {
unpackHandle.invoke(newUnpackerHandle.invoke(), in, out);
} catch (IOException | RuntimeException | Error e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static void unpack(File in, JarOutputStream out) throws IOException {
if (newUnpackerHandle == null) {
throw new UnsupportedOperationException("Pack200");
}
try {
unpackFileHandle.invoke(newUnpackerHandle.invoke(), in, out);
} catch (IOException | RuntimeException | Error e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
@@ -831,4 +831,21 @@
1.21.7-rc2
1.21.7
1.21.8-rc1
1.21.8
1.21.8
25w31a
25w32a
25w33a
25w34a
25w34b
25w35a
25w36a
25w36b
25w37a
1.21.9-pre1
1.21.9-pre2
1.21.9-pre3
1.21.9-pre4
1.21.9-rc1
1.21.9
1.21.10-rc1
1.21.10
@@ -1,4 +1,4 @@
# https://gitlab.freedesktop.org/mesa/drm/-/blob/b65d6ede3ebe64dbde5805007ddef22f390f8050/data/amdgpu.ids
# https://gitlab.freedesktop.org/mesa/libdrm/-/blob/7d43d9b6fe5df4b234937fce9e51adb1b327ded1/data/amdgpu.ids
#
# List of AMDGPU IDs
#
@@ -591,7 +591,9 @@
74B6, 00, AMD Instinct MI308X
74BD, 00, AMD Instinct MI300X HF
7550, C0, AMD Radeon RX 9070 XT
7550, C2, AMD Radeon RX 9070 GRE
7550, C3, AMD Radeon RX 9070
7551, C0, AMD Radeon AI PRO R9700
9830, 00, AMD Radeon HD 8400 / R3 Series
9831, 00, AMD Radeon HD 8400E
9832, 00, AMD Radeon HD 8330
@@ -13,6 +13,7 @@ public final class JavaRuntimeTest {
public void testParseVersion() {
assertEquals(8, parseVersion("1.8.0_302"));
assertEquals(8, parseVersion("1.8-internal"));
assertEquals(8, parseVersion("8.0"));
assertEquals(11, parseVersion("11"));
assertEquals(11, parseVersion("11.0.12"));
assertEquals(11, parseVersion("11-internal"));
+8 -1
View File
@@ -18,7 +18,14 @@ subprojects {
name = "libs"
dirs = setOf(rootProject.file("lib"))
}
mavenCentral()
System.getenv("MAVEN_CENTRAL_REPO").let { repo ->
if (repo.isNullOrBlank())
mavenCentral()
else
maven(url = repo)
}
maven(url = "https://jitpack.io")
maven(url = "https://libraries.minecraft.net")
}
+6 -1
View File
@@ -1,5 +1,10 @@
repositories {
mavenCentral()
System.getenv("MAVEN_CENTRAL_REPO").let { repo ->
if (repo.isNullOrBlank())
mavenCentral()
else
maven(url = repo)
}
}
dependencies {
@@ -0,0 +1,32 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2025 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.gradle.ci;
import java.util.Objects;
/// @author Glavo
public final class GitHubActionUtils {
private static final String OFFICIAL_ORGANIZATION = "HMCL-dev";
public static final boolean IS_ON_OFFICIAL_REPO =
OFFICIAL_ORGANIZATION.equalsIgnoreCase(System.getenv("GITHUB_REPOSITORY_OWNER"))
&& Objects.requireNonNullElse(System.getenv("GITHUB_BASE_REF"), "").isBlank();
private GitHubActionUtils() {
}
}
@@ -0,0 +1,27 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2025 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.gradle.ci;
/// @author Glavo
public final class JenkinsUtils {
public static final boolean IS_ON_CI = "1".equals(System.getenv("HMCL_CI"));
private JenkinsUtils() {
}
}
@@ -0,0 +1,39 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2025 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.gradle.utils;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
/// @author Glavo
public final class PropertiesUtils {
public static @NotNull Properties load(Path path) throws IOException {
Properties properties = new Properties();
try (var reader = Files.newBufferedReader(path)) {
properties.load(reader);
}
return properties;
}
private PropertiesUtils() {
}
}
-5
View File
@@ -1,5 +0,0 @@
#!/usr/bin/env bash
_HMCL_PROJECT_ROOT=$(dirname "${BASH_SOURCE[0]}")
sed -i 's,//services.gradle.org/distributions/,//mirrors.cloud.tencent.com/gradle/,g' "$_HMCL_PROJECT_ROOT/gradle/wrapper/gradle-wrapper.properties"
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
sed -i 's,//services.gradle.org/distributions/,//mirrors.cloud.tencent.com/gradle/,g' "$PWD/gradle/wrapper/gradle-wrapper.properties"
+23
View File
@@ -0,0 +1,23 @@
pipeline {
agent any
environment {
HMCL_CI = '1'
VERSION_TYPE = 'dev'
MICROSOFT_AUTH_ID = credentials('microsoft_auth_id')
MICROSOFT_AUTH_SECRET = credentials('microsoft_auth_secret')
CURSEFORGE_API_KEY = credentials('curseforge_api_key')
HMCL_SIGNATURE_KEY = credentials('hmcl_signature_key')
}
stages {
stage('Build') {
steps {
sh 'bash ./config/jenkins/config-jenkins.sh'
sh './gradlew clean makeExecutables --stacktrace --no-daemon'
archiveArtifacts artifacts: 'HMCL/build/libs/*'
}
}
}
}
+23
View File
@@ -0,0 +1,23 @@
pipeline {
agent any
environment {
HMCL_CI = '1'
VERSION_TYPE = 'stable'
MICROSOFT_AUTH_ID = credentials('microsoft_auth_id')
MICROSOFT_AUTH_SECRET = credentials('microsoft_auth_secret')
CURSEFORGE_API_KEY = credentials('curseforge_api_key')
HMCL_SIGNATURE_KEY = credentials('hmcl_signature_key')
}
stages {
stage('Build') {
steps {
sh 'bash ./config/jenkins/config-jenkins.sh'
sh './gradlew clean makeExecutables --stacktrace --no-daemon'
archiveArtifacts artifacts: 'HMCL/build/libs/*'
}
}
}
}
+18
View File
@@ -0,0 +1,18 @@
#
# Hello Minecraft! Launcher
# Copyright (C) 2025 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/>.
#
versionRoot=3.6