feat(i18n): 国际化与本地化基础#2799
Conversation
审阅者指南引入一个启动器范围的本地化系统,使 UI 语言、格式化区域文化以及特定语言的字体配置文件可以在运行时进行配置;将其接入到设置导航、字体选择以及 Minecraft 预运行阶段的语言/字体处理中,并添加测试来验证语言资源和字体配置文件解析的正确性。 从配置应用本地化并更新字体的时序图sequenceDiagram
actor User
participant SettingsUI
participant Config
participant LocalizationService
participant ApplicationResources
participant LocalizationFontService
participant FontSelector
User->>SettingsUI: change UiLanguage or UiFormatCulture
SettingsUI->>Config: update Preference.Localization values
Config-->>LocalizationService: trigger OnLanguageConfigChanged
LocalizationService->>LocalizationService: ApplyFromConfig(save=true)
LocalizationService->>Config: read Localization.Language and FormatCulture
LocalizationService->>LocalizationService: ResolveLanguage(languageCode)
LocalizationService->>LocalizationService: _ResolveFormatCulture(formatCultureCode, uiCulture)
LocalizationService->>LocalizationService: _ApplyCultures(uiCulture, formatCulture)
LocalizationService->>ApplicationResources: _ApplyLanguageResources(languageCode)
LocalizationService->>LocalizationFontService: ApplyLaunchFont(Config.Preference.Font, language)
LocalizationFontService->>ApplicationResources: set LaunchFontFamily
LocalizationService-->>Config: persist normalized Language and FormatCulture
LocalizationService-->>LocalizationService: update CurrentLanguage and CurrentFormatCulture
LocalizationService-->>FontSelector: LanguageChanged event
FontSelector->>FontSelector: RefreshDefaultFont()
FontSelector->>LocalizationFontService: BuildLaunchFontFamily()
FontSelector->>FontSelector: update default CustomFontProperties.Font
Minecraft 预运行语言与字体处理的时序图sequenceDiagram
participant ModLaunch
participant ModMinecraft
participant LocalizationService
participant ModBase
participant McConfigIni as McConfigIni
ModLaunch->>McConfigIni: ReadIni(lang)
McConfigIni-->>ModLaunch: currentLang
ModLaunch->>ModMinecraft: check saves directory
ModMinecraft-->>ModLaunch: hasExistingSaves
ModLaunch->>ModLaunch: isLanguageUnconfigured = (currentLang == none)
ModLaunch->>ModLaunch: shouldUseDefault = isLanguageUnconfigured or !hasExistingSaves
ModLaunch->>ModMinecraft: get ReleaseTime
ModMinecraft-->>ModLaunch: mcReleaseTime
ModLaunch->>ModLaunch: requiredLang = _ResolveMinecraftLanguage(currentLang, shouldUseDefault, mcReleaseTime)
ModLaunch->>ModLaunch: compare currentLang and requiredLang
alt language changed
ModLaunch->>McConfigIni: WriteIni(lang, "-")
ModLaunch->>McConfigIni: WriteIni(lang, requiredLang)
end
ModLaunch->>ModLaunch: if (isLanguageUnconfigured or !hasExistingSaves) and _ShouldEnableForceUnicodeFont()
ModLaunch->>LocalizationService: CurrentLanguage
LocalizationService-->>ModLaunch: LocalizationLanguage with FontProfile
ModLaunch->>ModLaunch: _ShouldEnableForceUnicodeFont() based on FontProfile
alt forceUnicodeFont enabled
ModLaunch->>McConfigIni: WriteIni(forceUnicodeFont, true)
end
新本地化系统(LocalizationService 及相关类型)的类图classDiagram
class LocalizationService {
<<service>>
+const string Auto
+const string FormatCultureFollowLanguage
+const string DefaultLanguageCode
+static LocalizationLanguage CurrentLanguage
+static CultureInfo CurrentFormatCulture
+static IReadOnlyList~LocalizationLanguage~ SupportedLanguages
+static event Action LanguageChanged
+static void ApplyFromConfig(bool save)
+static void Apply(string languageCode, string formatCultureCode, bool save)
+static bool IsLanguageSupported(string languageCode)
+static LocalizationLanguage ResolveLanguage(string languageCode)
-static void _Start()
-static void _ApplyCultures(CultureInfo uiCulture, CultureInfo formatCulture)
-static void _ApplyLanguageResources(string languageCode, CultureInfo uiCulture, CultureInfo formatCulture)
-static void _ApplyLanguageResourcesCore(Application app, string languageCode)
-static CultureInfo _ResolveFormatCulture(string formatCultureCode, CultureInfo uiCulture, out string normalizedCode)
-static LocalizationLanguage _ResolveSystemLanguage()
-static void _SaveConfigIfNeeded(bool save, string normalizedLanguageCode, LocalizationLanguage language, string normalizedFormatCultureCode)
}
class LocalizationLanguage {
+string Code
+string NativeName
+string CultureName
+LocalizationFontProfile FontProfile
}
class LocalizationFontProfile {
<<enum>>
English
SimplifiedChinese
TraditionalChinese
Japanese
Korean
Other
}
class LocalizationFontService {
<<static>>
-const string PclEnglishFont
-Uri _ApplicationPackUri
+FontFamily BuildLaunchFontFamily(string customFontName, LocalizationLanguage language)
+FontFamily BuildRepresentativeFontFamily(LocalizationLanguage language)
+FontFamily BuildRepresentativeFontFamily(LocalizationFontProfile profile)
+void ApplyLaunchFont(string customFontName, LocalizationLanguage language)
+LocalizationFontProfile ResolveProfileFromCultureName(string cultureName)
-IReadOnlyList~string~ _GetDefaultFamilyNames(LocalizationFontProfile profile)
-IReadOnlyList~string~ _GetCustomFamilyNames(string customFontName, LocalizationFontProfile profile)
}
class Lang {
<<static>>
+string Text(string key)
+string Text(string key, object[] args)
+string Date(DateTime value, string format)
+string Number~T~(T value, string format)
-object _LifecycleSafeFindResource(string key)
}
class LocalizationFormatConverter {
+object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
}
class LocalizationConfigGroup {
+string Language
+string FormatCulture
+string Region
}
class ConfigPreferenceLocalization {
+LocalizationConfigGroup Localization
}
class FontSelector {
+ObservableCollection~CustomFontProperties~ CustomFontCollection
+string Tooltip
+string SelectedFontTag
+int SelectedIndex
+event SelectionChangedEventHandler SelectionChanged
+void LoadFonts()
+void RefreshDefaultFont()
+void StartListeningLanguageChanged()
+void StopListeningLanguageChanged()
+void LocalizationService_LanguageChanged()
}
class CustomFontProperties {
+string Name
+FontFamily Font
+string Tag
+event PropertyChangedEventHandler PropertyChanged
-void SetField~T~(T field, T value, string propertyName)
}
class ModBase {
+static void SetLaunchFont(string FontName)
}
LocalizationService --> LocalizationLanguage : uses
LocalizationService --> LocalizationFontService : ApplyLaunchFont
LocalizationService --> LocalizationFontProfile : CurrentLanguage.FontProfile
LocalizationService --> LocalizationConfigGroup : reads
LocalizationFontService --> LocalizationFontProfile : ResolveProfileFromCultureName
LocalizationFontService --> LocalizationLanguage : BuildLaunchFontFamily
Lang --> LocalizationService : uses cultures
LocalizationFormatConverter --> LocalizationService : uses CultureInfo
ConfigPreferenceLocalization o-- LocalizationConfigGroup
FontSelector --> LocalizationFontService : BuildLaunchFontFamily
FontSelector ..> LocalizationService : subscribes LanguageChanged
FontSelector o-- CustomFontProperties
ModBase --> LocalizationFontService : ApplyLaunchFont
ModBase --> LocalizationService : CurrentLanguage
文件级改动
技巧与命令与 Sourcery 交互
自定义你的体验访问你的 控制面板,以便:
获取帮助Original review guide in EnglishReviewer's GuideIntroduce a launcher-wide localization system with runtime-configurable UI language, formatting culture, and language-specific font profiles, wire it into setup navigation, font selection, and Minecraft pre-run language/font handling, and add tests to validate language resources and font profile resolution. Sequence diagram for applying localization from config and updating fontssequenceDiagram
actor User
participant SettingsUI
participant Config
participant LocalizationService
participant ApplicationResources
participant LocalizationFontService
participant FontSelector
User->>SettingsUI: change UiLanguage or UiFormatCulture
SettingsUI->>Config: update Preference.Localization values
Config-->>LocalizationService: trigger OnLanguageConfigChanged
LocalizationService->>LocalizationService: ApplyFromConfig(save=true)
LocalizationService->>Config: read Localization.Language and FormatCulture
LocalizationService->>LocalizationService: ResolveLanguage(languageCode)
LocalizationService->>LocalizationService: _ResolveFormatCulture(formatCultureCode, uiCulture)
LocalizationService->>LocalizationService: _ApplyCultures(uiCulture, formatCulture)
LocalizationService->>ApplicationResources: _ApplyLanguageResources(languageCode)
LocalizationService->>LocalizationFontService: ApplyLaunchFont(Config.Preference.Font, language)
LocalizationFontService->>ApplicationResources: set LaunchFontFamily
LocalizationService-->>Config: persist normalized Language and FormatCulture
LocalizationService-->>LocalizationService: update CurrentLanguage and CurrentFormatCulture
LocalizationService-->>FontSelector: LanguageChanged event
FontSelector->>FontSelector: RefreshDefaultFont()
FontSelector->>LocalizationFontService: BuildLaunchFontFamily()
FontSelector->>FontSelector: update default CustomFontProperties.Font
Sequence diagram for Minecraft pre-run language and font handlingsequenceDiagram
participant ModLaunch
participant ModMinecraft
participant LocalizationService
participant ModBase
participant McConfigIni as McConfigIni
ModLaunch->>McConfigIni: ReadIni(lang)
McConfigIni-->>ModLaunch: currentLang
ModLaunch->>ModMinecraft: check saves directory
ModMinecraft-->>ModLaunch: hasExistingSaves
ModLaunch->>ModLaunch: isLanguageUnconfigured = (currentLang == none)
ModLaunch->>ModLaunch: shouldUseDefault = isLanguageUnconfigured or !hasExistingSaves
ModLaunch->>ModMinecraft: get ReleaseTime
ModMinecraft-->>ModLaunch: mcReleaseTime
ModLaunch->>ModLaunch: requiredLang = _ResolveMinecraftLanguage(currentLang, shouldUseDefault, mcReleaseTime)
ModLaunch->>ModLaunch: compare currentLang and requiredLang
alt language changed
ModLaunch->>McConfigIni: WriteIni(lang, "-")
ModLaunch->>McConfigIni: WriteIni(lang, requiredLang)
end
ModLaunch->>ModLaunch: if (isLanguageUnconfigured or !hasExistingSaves) and _ShouldEnableForceUnicodeFont()
ModLaunch->>LocalizationService: CurrentLanguage
LocalizationService-->>ModLaunch: LocalizationLanguage with FontProfile
ModLaunch->>ModLaunch: _ShouldEnableForceUnicodeFont() based on FontProfile
alt forceUnicodeFont enabled
ModLaunch->>McConfigIni: WriteIni(forceUnicodeFont, true)
end
Class diagram for new localization system (LocalizationService and related types)classDiagram
class LocalizationService {
<<service>>
+const string Auto
+const string FormatCultureFollowLanguage
+const string DefaultLanguageCode
+static LocalizationLanguage CurrentLanguage
+static CultureInfo CurrentFormatCulture
+static IReadOnlyList~LocalizationLanguage~ SupportedLanguages
+static event Action LanguageChanged
+static void ApplyFromConfig(bool save)
+static void Apply(string languageCode, string formatCultureCode, bool save)
+static bool IsLanguageSupported(string languageCode)
+static LocalizationLanguage ResolveLanguage(string languageCode)
-static void _Start()
-static void _ApplyCultures(CultureInfo uiCulture, CultureInfo formatCulture)
-static void _ApplyLanguageResources(string languageCode, CultureInfo uiCulture, CultureInfo formatCulture)
-static void _ApplyLanguageResourcesCore(Application app, string languageCode)
-static CultureInfo _ResolveFormatCulture(string formatCultureCode, CultureInfo uiCulture, out string normalizedCode)
-static LocalizationLanguage _ResolveSystemLanguage()
-static void _SaveConfigIfNeeded(bool save, string normalizedLanguageCode, LocalizationLanguage language, string normalizedFormatCultureCode)
}
class LocalizationLanguage {
+string Code
+string NativeName
+string CultureName
+LocalizationFontProfile FontProfile
}
class LocalizationFontProfile {
<<enum>>
English
SimplifiedChinese
TraditionalChinese
Japanese
Korean
Other
}
class LocalizationFontService {
<<static>>
-const string PclEnglishFont
-Uri _ApplicationPackUri
+FontFamily BuildLaunchFontFamily(string customFontName, LocalizationLanguage language)
+FontFamily BuildRepresentativeFontFamily(LocalizationLanguage language)
+FontFamily BuildRepresentativeFontFamily(LocalizationFontProfile profile)
+void ApplyLaunchFont(string customFontName, LocalizationLanguage language)
+LocalizationFontProfile ResolveProfileFromCultureName(string cultureName)
-IReadOnlyList~string~ _GetDefaultFamilyNames(LocalizationFontProfile profile)
-IReadOnlyList~string~ _GetCustomFamilyNames(string customFontName, LocalizationFontProfile profile)
}
class Lang {
<<static>>
+string Text(string key)
+string Text(string key, object[] args)
+string Date(DateTime value, string format)
+string Number~T~(T value, string format)
-object _LifecycleSafeFindResource(string key)
}
class LocalizationFormatConverter {
+object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
}
class LocalizationConfigGroup {
+string Language
+string FormatCulture
+string Region
}
class ConfigPreferenceLocalization {
+LocalizationConfigGroup Localization
}
class FontSelector {
+ObservableCollection~CustomFontProperties~ CustomFontCollection
+string Tooltip
+string SelectedFontTag
+int SelectedIndex
+event SelectionChangedEventHandler SelectionChanged
+void LoadFonts()
+void RefreshDefaultFont()
+void StartListeningLanguageChanged()
+void StopListeningLanguageChanged()
+void LocalizationService_LanguageChanged()
}
class CustomFontProperties {
+string Name
+FontFamily Font
+string Tag
+event PropertyChangedEventHandler PropertyChanged
-void SetField~T~(T field, T value, string propertyName)
}
class ModBase {
+static void SetLaunchFont(string FontName)
}
LocalizationService --> LocalizationLanguage : uses
LocalizationService --> LocalizationFontService : ApplyLaunchFont
LocalizationService --> LocalizationFontProfile : CurrentLanguage.FontProfile
LocalizationService --> LocalizationConfigGroup : reads
LocalizationFontService --> LocalizationFontProfile : ResolveProfileFromCultureName
LocalizationFontService --> LocalizationLanguage : BuildLaunchFontFamily
Lang --> LocalizationService : uses cultures
LocalizationFormatConverter --> LocalizationService : uses CultureInfo
ConfigPreferenceLocalization o-- LocalizationConfigGroup
FontSelector --> LocalizationFontService : BuildLaunchFontFamily
FontSelector ..> LocalizationService : subscribes LanguageChanged
FontSelector o-- CustomFontProperties
ModBase --> LocalizationFontService : ApplyLaunchFont
ModBase --> LocalizationService : CurrentLanguage
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
还是那个老问题,内置的
本人能想到的有两种解决办法:
下图展示了 PCL English(下)和 Bahnschrift Light(上)的区别。两者极为相似,只有仔细对比观察才能发现区别。因此可以考虑作为替代字体。
Edited: 暂时选择方案一为解决办法,待讨论。 |
This comment was marked as resolved.
This comment was marked as resolved.
- duplicated Reload() - language change short-circuit check
This comment was marked as resolved.
This comment was marked as resolved.
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo








实现 i18n 与 l10n 的基础能力。
待办:
管理 -> 辅助功能中的游戏语言以跟随启动器语言Summary by Sourcery
为启动器引入一个全局本地化系统,用于 UI 语言和格式化区域设置,将其集成到设置中,并与 Minecraft 启动行为和字体处理进行连接。
New Features:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Introduce a launcher-wide localization system for UI language and formatting culture, integrate it into settings, and connect it with Minecraft launch behavior and font handling.
New Features:
Enhancements:
Tests: