diff --git a/UXAssist/Common/I18N.cs b/UXAssist/Common/I18N.cs
index c53e5d1..a237470 100644
--- a/UXAssist/Common/I18N.cs
+++ b/UXAssist/Common/I18N.cs
@@ -4,34 +4,60 @@ using HarmonyLib;
namespace UXAssist.Common;
+///
+/// Provides bilingual localization helpers that integrate with the game's system.
+///
public static class I18N
{
private static bool _initialized;
private static bool _dirty;
+ ///
+ /// Invoked after the game has finished loading the active language and all registered strings have been applied.
+ ///
public static Action OnInitialized;
+ ///
+ /// Registers the localization hooks with Harmony.
+ ///
public static void Init()
{
Harmony.CreateAndPatchAll(typeof(I18N));
}
+ ///
+ /// Returns whether the localization system has finished its initial load.
+ ///
+ /// true if localization is initialized; otherwise false.
public static bool Initialized() => _initialized;
- private static readonly List> Keys = [];
- private static readonly Dictionary> Strings = [];
- public static void Add(string key, string enus, string zhcn = null)
+ ///
+ /// Holds the English and Simplified Chinese localized values for a single entry.
+ ///
+ private sealed class LocalizedString
{
- if (zhcn == null && key == enus) return;
- Keys.Add(Tuple.Create(key, enus, -1));
- if (Strings.TryGetValue(2052, out var zhcnList))
+ public string En { get; }
+ public string Zh { get; }
+
+ public LocalizedString(string en, string zh)
{
- zhcnList.Add(string.IsNullOrEmpty(zhcn) ? enus : zhcn);
- }
- else
- {
- Strings.Add(2052, [string.IsNullOrEmpty(zhcn) ? enus : zhcn]);
+ En = en;
+ Zh = zh;
}
+ }
+
+ private static readonly Dictionary Entries = new();
+
+ ///
+ /// Registers a localized string pair.
+ ///
+ /// The lookup key.
+ /// The English text.
+ /// The Simplified Chinese text.
+ public static void Add(string key, string en, string zh)
+ {
+ if (zh is null && key == en) return;
+ Entries[key] = new LocalizedString(en, string.IsNullOrEmpty(zh) ? en : zh);
_dirty = true;
}
@@ -39,25 +65,17 @@ public static class I18N
{
var indexer = Localization.namesIndexer;
var index = indexer.Count;
- var len = Keys.Count;
- for (var i = 0; i < len; i++)
+ foreach (var key in Entries.Keys)
{
- var (key, def, value) = Keys[i];
- if (value >= 0) continue;
- if (indexer.TryGetValue(key, out var idx))
- {
- Keys[i] = Tuple.Create(key, def, idx);
- continue;
- }
+ if (indexer.TryGetValue(key, out _)) continue;
indexer[key] = index;
- Keys[i] = Tuple.Create(key, def, index);
index++;
}
_dirty = false;
var strings = Localization.strings;
if (strings == null) return;
- var len2 = strings.Length;
- for (var i = 0; i < len2; i++)
+ var len = strings.Length;
+ for (var i = 0; i < len; i++)
{
ApplyLanguage(i);
if (i != Localization.currentLanguageIndex) continue;
@@ -90,31 +108,40 @@ public static class I18N
}
}
- var keyLength = Keys.Count;
- if (Strings.TryGetValue(Localization.Languages[index].lcId, out var list))
+ var isChinese = Localization.Languages[index].lcId == 2052;
+ foreach (var entry in Entries)
{
- for (var j = 0; j < keyLength; j++)
- {
- strs[Keys[j].Item3] = list[j];
- }
- }
- else
- {
- for (var j = 0; j < keyLength; j++)
- {
- strs[Keys[j].Item3] = Keys[j].Item2;
- }
+ if (!Localization.namesIndexer.TryGetValue(entry.Key, out var idx)) continue;
+ strs[idx] = isChinese ? entry.Value.Zh : entry.Value.En;
}
}
+ ///
+ /// Applies any pending localization changes to the game's localization tables.
+ ///
public static void Apply()
{
if (!_initialized) return;
- if (Keys.Count == 0) return;
+ if (Entries.Count == 0) return;
if (!_dirty) return;
ApplyIndexers();
}
+ ///
+ /// Returns the localized text for the given key in the currently active language,
+ /// falling back to the key itself when no entry is registered.
+ ///
+ /// The lookup key.
+ /// The localized text, or if no entry exists.
+ public static string Translate(string key)
+ {
+ if (!Entries.TryGetValue(key, out var loc)) return key;
+ var languageIndex = Localization.currentLanguageIndex;
+ if (languageIndex >= 0 && languageIndex < Localization.Languages.Length && Localization.Languages[languageIndex].lcId == 2052)
+ return loc.Zh;
+ return loc.En;
+ }
+
[HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(Localization), nameof(Localization.LoadSettings))]
private static void Localization_LoadSettings_Postfix()
{
@@ -136,4 +163,4 @@ public static class I18N
if (!_initialized) return;
OnInitialized?.Invoke();
}
-}
\ No newline at end of file
+}