优化 Minecraft Wiki 跳转功能 (#4372)

This commit is contained in:
Glavo
2025-09-01 23:13:20 +08:00
committed by GitHub
parent 28b222e3dd
commit 10e5e7bc9c
12 changed files with 234 additions and 112 deletions

View File

@@ -190,12 +190,10 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
if (remoteVersion instanceof GameRemoteVersion) {
RemoteVersion.Type versionType = remoteVersion.getVersionType();
String wikiSuffix = getWikiUrlSuffix(remoteVersion.getGameVersion());
switch (versionType) {
case RELEASE:
content.getTags().setAll(i18n("version.game.release"));
content.setImage(VersionIconType.GRASS.getIcon());
content.setExternalLink(i18n("wiki.version.game", wikiSuffix));
break;
case PENDING:
case SNAPSHOT:
@@ -207,14 +205,13 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
content.getTags().setAll(i18n("version.game.snapshot"));
content.setImage(VersionIconType.COMMAND.getIcon());
}
content.setExternalLink(i18n("wiki.version.game", wikiSuffix));
break;
default:
content.getTags().setAll(i18n("version.game.old"));
content.setImage(VersionIconType.CRAFT_TABLE.getIcon());
content.setExternalLink(i18n("wiki.version.game", wikiSuffix));
break;
}
content.setExternalLink(I18n.getWikiLink((GameRemoteVersion) remoteVersion));
} else {
VersionIconType iconType;
if (remoteVersion instanceof LiteLoaderRemoteVersion)
@@ -240,75 +237,6 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
content.setExternalLink(null);
}
}
private String getWikiUrlSuffix(String gameVersion) {
String id = gameVersion.toLowerCase(Locale.ROOT);
switch (id) {
case "0.30-1":
case "0.30-2":
case "c0.30_01c":
return i18n("wiki.version.game.search", "Classic_0.30");
case "in-20100206-2103":
return i18n("wiki.version.game.search", "Indev_20100206");
case "inf-20100630-1":
return i18n("wiki.version.game.search", "Infdev_20100630");
case "inf-20100630-2":
return i18n("wiki.version.game.search", "Alpha_v1.0.0");
case "1.19_deep_dark_experimental_snapshot-1":
return "1.19-exp1";
case "in-20100130":
return i18n("wiki.version.game.search", "Indev_0.31_20100130");
case "b1.6-tb3":
return i18n("wiki.version.game.search", "Beta_1.6_Test_Build_3");
case "1.14_combat-212796":
return i18n("wiki.version.game.search", "1.14.3_-_Combat_Test");
case "1.14_combat-0":
return i18n("wiki.version.game.search", "Combat_Test_2");
case "1.14_combat-3":
return i18n("wiki.version.game.search", "Combat_Test_3");
case "1_15_combat-1":
return i18n("wiki.version.game.search", "Combat_Test_4");
case "1_15_combat-6":
return i18n("wiki.version.game.search", "Combat_Test_5");
case "1_16_combat-0":
return i18n("wiki.version.game.search", "Combat_Test_6");
case "1_16_combat-1":
return i18n("wiki.version.game.search", "Combat_Test_7");
case "1_16_combat-2":
return i18n("wiki.version.game.search", "Combat_Test_7b");
case "1_16_combat-3":
return i18n("wiki.version.game.search", "Combat_Test_7c");
case "1_16_combat-4":
return i18n("wiki.version.game.search", "Combat_Test_8");
case "1_16_combat-5":
return i18n("wiki.version.game.search", "Combat_Test_8b");
case "1_16_combat-6":
return i18n("wiki.version.game.search", "Combat_Test_8c");
}
if (id.startsWith("1.0.0-rc2")) return "RC2";
if (id.startsWith("2.0")) return i18n("wiki.version.game.search", "2.0");
if (id.startsWith("b1.8-pre1")) return "Beta_1.8-pre1";
if (id.startsWith("b1.1-")) return i18n("wiki.version.game.search", "Beta_1.1");
if (id.startsWith("a1.1.0")) return "Alpha_v1.1.0";
if (id.startsWith("a1.0.14")) return "Alpha_v1.0.14";
if (id.startsWith("a1.0.13_01")) return "Alpha_v1.0.13_01";
if (id.startsWith("in-20100214")) return i18n("wiki.version.game.search", "Indev_20100214");
if (id.contains("experimental-snapshot")) {
return id.replace("_experimental-snapshot-", "-exp");
}
if (id.startsWith("inf-")) return id.replace("inf-", "Infdev_");
if (id.startsWith("in-")) return id.replace("in-", "Indev_");
if (id.startsWith("rd-")) return "pre-Classic_" + id;
if (id.startsWith("b")) return id.replace("b", "Beta_");
if (id.startsWith("a")) return id.replace("a", "Alpha_v");
if (id.startsWith("c")) return id.replace("c", "Classic_").replace("st", "SURVIVAL_TEST");
return i18n("wiki.version.game.search", id);
}
}
private static final class VersionsPageSkin extends SkinBase<VersionsPage> {

View File

@@ -18,13 +18,12 @@
package org.jackhuang.hmcl.util.i18n;
import org.jackhuang.hmcl.download.RemoteVersion;
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale;
import java.time.temporal.TemporalAccessor;
import java.util.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public final class I18n {
private I18n() {
@@ -51,24 +50,11 @@ public final class I18n {
}
public static String i18n(String key, Object... formatArgs) {
try {
return String.format(getResourceBundle().getString(key), formatArgs);
} catch (MissingResourceException e) {
LOG.error("Cannot find key " + key + " in resource bundle", e);
} catch (IllegalFormatException e) {
LOG.error("Illegal format string, key=" + key + ", args=" + Arrays.toString(formatArgs), e);
}
return key + Arrays.toString(formatArgs);
return locale.i18n(key, formatArgs);
}
public static String i18n(String key) {
try {
return getResourceBundle().getString(key);
} catch (MissingResourceException e) {
LOG.error("Cannot find key " + key + " in resource bundle", e);
return key;
}
return locale.i18n(key);
}
public static String formatDateTime(TemporalAccessor time) {
@@ -79,6 +65,10 @@ public final class I18n {
return locale.getDisplaySelfVersion(version);
}
public static String getWikiLink(GameRemoteVersion remoteVersion) {
return MinecraftWiki.getWikiLink(locale, remoteVersion);
}
public static boolean hasKey(String key) {
return getResourceBundle().containsKey(key);
}

View File

@@ -188,6 +188,27 @@ public final class Locales {
return bundle;
}
public String i18n(String key, Object... formatArgs) {
try {
return String.format(getResourceBundle().getString(key), formatArgs);
} catch (MissingResourceException e) {
LOG.error("Cannot find key " + key + " in resource bundle", e);
} catch (IllegalFormatException e) {
LOG.error("Illegal format string, key=" + key + ", args=" + Arrays.toString(formatArgs), e);
}
return key + Arrays.toString(formatArgs);
}
public String i18n(String key) {
try {
return getResourceBundle().getString(key);
} catch (MissingResourceException e) {
LOG.error("Cannot find key " + key + " in resource bundle", e);
return key;
}
}
public String formatDateTime(TemporalAccessor time) {
DateTimeFormatter formatter = dateTimeFormatter;
if (formatter == null)
@@ -202,7 +223,7 @@ public final class Locales {
public String getFcMatchPattern() {
String language = locale.getLanguage();
String country = locale.getCountry();
String region = locale.getCountry();
if (isEnglish(locale))
return "";
@@ -212,13 +233,13 @@ public final class Locales {
String charset;
if (isSimplifiedChinese(locale)) {
lang = country.equals("SG") || country.equals("MY")
? "zh-" + country
lang = region.equals("SG") || region.equals("MY")
? "zh-" + region
: "zh-CN";
charset = "0x6e38,0x620f";
} else {
lang = country.equals("HK") || country.equals("MO")
? "zh-" + country
lang = region.equals("HK") || region.equals("MO")
? "zh-" + region
: "zh-TW";
charset = "0x904a,0x6232";
}
@@ -226,7 +247,7 @@ public final class Locales {
return ":lang=" + lang + ":charset=" + charset;
}
return country.isEmpty() ? language : language + "-" + country;
return region.isEmpty() ? language : language + "-" + region;
}
public boolean isSameLanguage(SupportedLocale other) {

View File

@@ -0,0 +1,183 @@
/*
* 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.util.i18n;
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
import java.util.Locale;
import java.util.regex.Pattern;
public final class MinecraftWiki {
private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("^[0-9]{2}w[0-9]{2}.+$");
public static String getWikiLink(Locales.SupportedLocale locale, GameRemoteVersion version) {
String wikiVersion = version.getSelfVersion();
var gameVersion = GameVersionNumber.asGameVersion(wikiVersion);
if (locale.getLocale().getLanguage().equals("lzh")) {
String translatedVersion;
if (wikiVersion.startsWith("2.0"))
translatedVersion = "二點〇";
else if (wikiVersion.startsWith("1.0.0-rc2"))
translatedVersion = WenyanUtils.translateGameVersion(GameVersionNumber.asGameVersion("1.0.0-rc2"));
else
translatedVersion = WenyanUtils.translateGameVersion(gameVersion);
if (translatedVersion.equals(gameVersion.toString()) || gameVersion instanceof GameVersionNumber.Old) {
return getWikiLink(Locales.ZH_HANT, version);
} else if (SNAPSHOT_PATTERN.matcher(wikiVersion).matches()) {
return locale.i18n("wiki.version.game.snapshot", translatedVersion);
} else {
return locale.i18n("wiki.version.game", translatedVersion);
}
}
String variantSuffix;
if (Locales.isChinese(locale.getLocale())) {
if (Locales.isSimplifiedChinese(locale.getLocale()))
variantSuffix = "?variant=zh-cn";
else if (locale.getLocale().getCountry().equals("HK") || locale.getLocale().getCountry().equals("MO"))
variantSuffix = "?variant=zh-hk";
else
variantSuffix = "?variant=zh-tw";
} else
variantSuffix = "";
replace:
if (gameVersion instanceof GameVersionNumber.Release) {
if (wikiVersion.startsWith("1.0")) {
if (wikiVersion.equals("1.0"))
wikiVersion = "1.0.0";
else if (wikiVersion.startsWith("1.0.0-rc2"))
wikiVersion = "1.0.0-rc2";
}
} else if (gameVersion instanceof GameVersionNumber.Snapshot) {
return locale.i18n("wiki.version.game.snapshot", wikiVersion) + variantSuffix;
} else {
if (wikiVersion.length() >= 6 && wikiVersion.charAt(2) == 'w') {
// Starting from 2020, all April Fools' versions follow this pattern
if (SNAPSHOT_PATTERN.matcher(wikiVersion).matches()) {
if (wikiVersion.equals("22w13oneblockatatime"))
wikiVersion = "22w13oneBlockAtATime";
return locale.i18n("wiki.version.game.snapshot", wikiVersion) + variantSuffix;
}
}
String lower = wikiVersion.toLowerCase(Locale.ROOT);
switch (lower) {
case "0.30-1":
case "0.30-2":
case "c0.30_01c":
wikiVersion = "Classic_0.30";
break replace;
case "in-20100206-2103":
wikiVersion = "Indev_20100206";
break replace;
case "inf-20100630-1":
wikiVersion = "Infdev_20100630";
break replace;
case "inf-20100630-2":
wikiVersion = "Alpha_v1.0.0";
break replace;
case "1.19_deep_dark_experimental_snapshot-1":
wikiVersion = "1.19-exp1";
break replace;
case "in-20100130":
wikiVersion = "Indev_0.31_20100130";
break replace;
case "b1.6-tb3":
wikiVersion = "Beta_1.6_Test_Build_3";
break replace;
case "1.14_combat-212796":
wikiVersion = "1.14.3_-_Combat_Test";
break replace;
case "1.14_combat-0":
wikiVersion = "Combat_Test_2";
break replace;
case "1.14_combat-3":
wikiVersion = "Combat_Test_3";
break replace;
case "1_15_combat-1":
wikiVersion = "Combat_Test_4";
break replace;
case "1_15_combat-6":
wikiVersion = "Combat_Test_5";
break replace;
case "1_16_combat-0":
wikiVersion = "Combat_Test_6";
break replace;
case "1_16_combat-1":
wikiVersion = "Combat_Test_7";
break replace;
case "1_16_combat-2":
wikiVersion = "Combat_Test_7b";
break replace;
case "1_16_combat-3":
wikiVersion = "Combat_Test_7c";
break replace;
case "1_16_combat-4":
wikiVersion = "Combat_Test_8";
break replace;
case "1_16_combat-5":
wikiVersion = "Combat_Test_8b";
break replace;
case "1_16_combat-6":
wikiVersion = "Combat_Test_8c";
break replace;
}
if (lower.startsWith("2.0"))
wikiVersion = "2.0";
else if (lower.startsWith("b1.8-pre1"))
wikiVersion = "Beta_1.8-pre1";
else if (lower.startsWith("b1.1-"))
wikiVersion = "Beta_1.1";
else if (lower.startsWith("a1.1.0"))
wikiVersion = "Alpha_v1.1.0";
else if (lower.startsWith("a1.0.14"))
wikiVersion = "Alpha_v1.0.14";
else if (lower.startsWith("a1.0.13_01"))
wikiVersion = "Alpha_v1.0.13_01";
else if (lower.startsWith("in-20100214"))
wikiVersion = "Indev_20100214";
else if (lower.contains("experimental-snapshot"))
wikiVersion = lower.replace("_experimental-snapshot-", "-exp");
else if (lower.startsWith("inf-"))
wikiVersion = lower.replace("inf-", "Infdev_");
else if (lower.startsWith("in-"))
wikiVersion = lower.replace("in-", "Indev_");
else if (lower.startsWith("rd-"))
wikiVersion = "pre-Classic_" + lower;
else if (lower.startsWith("b"))
wikiVersion = lower.replace("b", "Beta_");
else if (lower.startsWith("a"))
wikiVersion = lower.replace("a", "Alpha_v");
else if (lower.startsWith("c"))
wikiVersion = lower
.replace("c", "Classic_")
.replace("st", "SURVIVAL_TEST");
}
return locale.i18n("wiki.version.game", wikiVersion) + variantSuffix;
}
private MinecraftWiki() {
}
}

View File

@@ -1483,8 +1483,8 @@ version.settings=Settings
version.update=Update Modpack
wiki.tooltip=Minecraft Wiki Page
wiki.version.game=https://minecraft.wiki/w/Special:Search?search=%s
wiki.version.game.search=Java_Edition_%s
wiki.version.game=https://minecraft.wiki/w/Java_Edition_%s
wiki.version.game.snapshot=https://minecraft.wiki/w/Java_Edition_%s
wizard.prev=< Prev
wizard.failed=Failed

View File

@@ -1482,8 +1482,8 @@ version.settings=Configuración
version.update=Actualizar Modpack
wiki.tooltip=Página de Minecraft Wiki
wiki.version.game=https://es.minecraft.wiki/w/Special:Search?search=%s
wiki.version.game.search=Java_Edition_%s
wiki.version.game=https://es.minecraft.wiki/w/Java_Edition_%s
wiki.version.game.snapshot=https://es.minecraft.wiki/w/Java_Edition_%s
wizard.prev=< Previo
wizard.failed=Falló

View File

@@ -962,8 +962,8 @@ version.manage.rename.fail=バージョンの名前を変更できませんで
version.settings=設定
version.update=modpackを更新する
wiki.version.game=https://ja.minecraft.wiki/w/Special:Search?search=%s
wiki.version.game.search=Java_Edition_%s
wiki.version.game=https://ja.minecraft.wiki/w/Java_Edition_%s
wiki.version.game.snapshot=https://ja.minecraft.wiki/w/Java_Edition_%s
wizard.prev=< 前へ
wizard.failed=失敗

View File

@@ -1196,8 +1196,8 @@ version.settings=規設
version.update=更改囊集
wiki.tooltip=礦藝大典
wiki.version.game=https://zh.minecraft.wiki/w/Special:Search?search=%s&variant=zh-tw
wiki.version.game.search=Java版%s
wiki.version.game=https://lzh.minecraft.wiki/w/爪哇版%s
wiki.version.game.snapshot=https://lzh.minecraft.wiki/w/%s
wizard.prev=< 前步
wizard.failed=未成

View File

@@ -1482,8 +1482,8 @@ version.settings=Настройки
version.update=Обновить модпак
wiki.tooltip=Страница Minecraft Wiki
wiki.version.game=https://ru.minecraft.wiki/w/Special:Search?search=%s
wiki.version.game.search=%s_(Java_Edition)
wiki.version.game=https://ru.minecraft.wiki/w/%s_(Java_Edition)
wiki.version.game.snapshot=https://ru.minecraft.wiki/w/%s_(Java_Edition)
wizard.prev=< Пред.
wizard.failed=Не удалось

View File

@@ -1427,8 +1427,8 @@ version.settings=Налаштування
version.update=Оновити модпак
wiki.tooltip=Сторінка Minecraft Wiki
wiki.version.game=https://uk.minecraft.wiki/w/Special:Search?search=%s
wiki.version.game.search=%s_(Java_Edition)
wiki.version.game=https://uk.minecraft.wiki/w/%s_(Java_Edition)
wiki.version.game.snapshot=https://uk.minecraft.wiki/w/%s_(Java_Edition)
wizard.prev=< Попередній
wizard.failed=Не вдалося

View File

@@ -1269,8 +1269,8 @@ version.settings=遊戲設定
version.update=更新模組包
wiki.tooltip=Minecraft Wiki 頁面
wiki.version.game=https://zh.minecraft.wiki/w/Special:Search?search=%s&variant=zh-tw
wiki.version.game.search=Java版%s
wiki.version.game=https://zh.minecraft.wiki/w/Java版%s
wiki.version.game.snapshot=https://zh.minecraft.wiki/w/%s
wizard.prev=< 上一步
wizard.failed=失敗

View File

@@ -1279,8 +1279,8 @@ version.settings=游戏设置
version.update=更新整合包
wiki.tooltip=Minecraft Wiki 页面
wiki.version.game=https://zh.minecraft.wiki/w/Special:Search?search=%s&variant=zh-cn
wiki.version.game.search=Java版%s
wiki.version.game=https://zh.minecraft.wiki/w/Java版%s
wiki.version.game.snapshot=https://zh.minecraft.wiki/w/%s
wizard.prev=< 上一步
wizard.failed=失败