using System; using System.Collections.Generic; using System.Collections.Immutable; using System.IO; using System.Linq; using Newtonsoft.Json; using UnityEditor; using UnityEngine; namespace nadena.dev.modular_avatar.core.editor { internal static class Localization { public static event Action OnLangChange; private const string FallbackLanguage = "en"; private const string localizationPathGuid = "488c994003974b3ab2796371cf627bca"; private static string localizationPathRoot = AssetDatabase.GUIDToAssetPath(localizationPathGuid); private static ImmutableDictionary SupportedLanguageDisplayNames = ImmutableDictionary.Empty .Add("en", "English") .Add("ja", "日本語") .Add("zh-hans", "简体中文") .Add("ko", "한국어"); private static ImmutableList SupportedLanguages = new string[] {"en", "ja", "zh-hans", "ko"}.ToImmutableList(); private static string[] DisplayNames = SupportedLanguages.Select(l => { return SupportedLanguageDisplayNames.TryGetValue(l, out var displayName) ? displayName : l; }).ToArray(); private static Dictionary> Cache = new Dictionary>(); internal static string OverrideLanguage { get; set; } = null; [MenuItem("Tools/Modular Avatar/Reload localizations")] public static void Reload() { Cache.Clear(); OnLangChange?.Invoke(); } private static ImmutableDictionary GetLocalization(string lang) { if (Cache.TryGetValue(lang, out var info)) { return info; } var fallback = lang == FallbackLanguage ? ImmutableDictionary.Empty : GetLocalization(FallbackLanguage); var filename = localizationPathRoot + "/" + lang + ".json"; try { var langData = File.ReadAllText(filename); var tmp = JsonConvert.DeserializeObject>(langData); foreach (var kvp in fallback) { if (!tmp.ContainsKey(kvp.Key)) { tmp[kvp.Key] = kvp.Value; } } info = tmp.ToImmutableDictionary(); Cache[lang] = info; return info; } catch (Exception e) { Debug.LogError("Failed to load language file " + filename); Debug.LogException(e); return ImmutableDictionary.Empty; } } public static GUIContent G(string key) { var tooltip = S(key + ".tooltip", null); return tooltip != null ? new GUIContent(S(key), tooltip) : new GUIContent(S(key)); } public static string S(string key) { return S(key, key); } public static string S(string key, string defValue) { var info = GetLocalization(GetSelectedLocalization()); if (info.TryGetValue(key, out var value)) { return value; } else { return defValue; } } public static string GetSelectedLocalization() { return OverrideLanguage ?? EditorPrefs.GetString("nadena.dev.modularavatar.lang", "en"); } public static void ShowLanguageUI() { EditorGUILayout.Separator(); var curLang = GetSelectedLocalization(); var curIndex = SupportedLanguages.IndexOf(curLang); var newIndex = EditorGUILayout.Popup("Editor Language", curIndex, DisplayNames); if (newIndex != curIndex) { EditorPrefs.SetString("nadena.dev.modularavatar.lang", SupportedLanguages[newIndex]); Reload(); } } } }