using System; using System.Collections.Generic; using UnityEngine; public static class Localization { public delegate byte[] LoadFunction(string path); public delegate void OnLocalizeNotification(); public static LoadFunction loadFunction; public static OnLocalizeNotification onLocalize; public static bool localizationHasBeenSet = false; private static string[] mLanguages = null; private static Dictionary mOldDictionary = new Dictionary(); private static Dictionary mDictionary = new Dictionary(); private static Dictionary mReplacement = new Dictionary(); private static int mLanguageIndex = -1; private static string mLanguage; private static bool mMerging = false; public static Dictionary dictionary { get { if (!localizationHasBeenSet) { LoadDictionary(PlayerPrefs.GetString("Language", "English")); } return mDictionary; } set { localizationHasBeenSet = value != null; mDictionary = value; } } public static string[] knownLanguages { get { if (!localizationHasBeenSet) { LoadDictionary(PlayerPrefs.GetString("Language", "English")); } return mLanguages; } } public static string language { get { if (string.IsNullOrEmpty(mLanguage)) { mLanguage = PlayerPrefs.GetString("Language", "English"); LoadAndSelect(mLanguage); } return mLanguage; } set { if (mLanguage != value) { mLanguage = value; LoadAndSelect(value); } } } [Obsolete("Localization is now always active. You no longer need to check this property.")] public static bool isActive => true; private static bool LoadDictionary(string value) { byte[] array = null; if (!localizationHasBeenSet) { if (loadFunction == null) { TextAsset textAsset = Resources.Load("Localization"); if (textAsset != null) { array = textAsset.bytes; } } else { array = loadFunction("Localization"); } localizationHasBeenSet = true; } if (LoadCSV(array)) { return true; } if (string.IsNullOrEmpty(value)) { value = mLanguage; } if (string.IsNullOrEmpty(value)) { return false; } if (loadFunction == null) { TextAsset textAsset2 = Resources.Load(value); if (textAsset2 != null) { array = textAsset2.bytes; } } else { array = loadFunction(value); } if (array != null) { Set(value, array); return true; } return false; } private static bool LoadAndSelect(string value) { if (!string.IsNullOrEmpty(value)) { if (mDictionary.Count == 0 && !LoadDictionary(value)) { return false; } if (SelectLanguage(value)) { return true; } } if (mOldDictionary.Count > 0) { return true; } mOldDictionary.Clear(); mDictionary.Clear(); if (string.IsNullOrEmpty(value)) { PlayerPrefs.DeleteKey("Language"); } return false; } public static void Load(TextAsset asset) { ByteReader byteReader = new ByteReader(asset); Set(asset.name, byteReader.ReadDictionary()); } public static void Set(string languageName, byte[] bytes) { ByteReader byteReader = new ByteReader(bytes); Set(languageName, byteReader.ReadDictionary()); } public static void ReplaceKey(string key, string val) { if (!string.IsNullOrEmpty(val)) { mReplacement[key] = val; } else { mReplacement.Remove(key); } } public static void ClearReplacements() { mReplacement.Clear(); } public static bool LoadCSV(TextAsset asset, bool merge = false) { return LoadCSV(asset.bytes, asset, merge); } public static bool LoadCSV(byte[] bytes, bool merge = false) { return LoadCSV(bytes, null, merge); } private static bool HasLanguage(string languageName) { int i = 0; for (int num = mLanguages.Length; i < num; i++) { if (mLanguages[i] == languageName) { return true; } } return false; } private static bool LoadCSV(byte[] bytes, TextAsset asset, bool merge = false) { if (bytes == null) { return false; } ByteReader byteReader = new ByteReader(bytes); BetterList betterList = byteReader.ReadCSV(); if (betterList.size < 2) { return false; } betterList.RemoveAt(0); string[] array = null; if (string.IsNullOrEmpty(mLanguage)) { localizationHasBeenSet = false; } if (!localizationHasBeenSet || (!merge && !mMerging) || mLanguages == null || mLanguages.Length == 0) { mDictionary.Clear(); mLanguages = new string[betterList.size]; if (!localizationHasBeenSet) { mLanguage = PlayerPrefs.GetString("Language", betterList[0]); localizationHasBeenSet = true; } for (int i = 0; i < betterList.size; i++) { mLanguages[i] = betterList[i]; if (mLanguages[i] == mLanguage) { mLanguageIndex = i; } } } else { array = new string[betterList.size]; for (int j = 0; j < betterList.size; j++) { array[j] = betterList[j]; } for (int k = 0; k < betterList.size; k++) { if (HasLanguage(betterList[k])) { continue; } int num = mLanguages.Length + 1; Array.Resize(ref mLanguages, num); mLanguages[num - 1] = betterList[k]; Dictionary dictionary = new Dictionary(); foreach (KeyValuePair item in mDictionary) { string[] array2 = item.Value; Array.Resize(ref array2, num); array2[num - 1] = array2[0]; dictionary.Add(item.Key, array2); } mDictionary = dictionary; } } Dictionary dictionary2 = new Dictionary(); for (int l = 0; l < mLanguages.Length; l++) { dictionary2.Add(mLanguages[l], l); } while (true) { BetterList betterList2 = byteReader.ReadCSV(); if (betterList2 == null || betterList2.size == 0) { break; } if (!string.IsNullOrEmpty(betterList2[0])) { AddCSV(betterList2, array, dictionary2); } } if (!mMerging && onLocalize != null) { mMerging = true; OnLocalizeNotification onLocalizeNotification = onLocalize; onLocalize = null; onLocalizeNotification(); onLocalize = onLocalizeNotification; mMerging = false; } return true; } private static void AddCSV(BetterList newValues, string[] newLanguages, Dictionary languageIndices) { if (newValues.size < 2) { return; } string text = newValues[0]; if (string.IsNullOrEmpty(text)) { return; } string[] value = ExtractStrings(newValues, newLanguages, languageIndices); if (mDictionary.ContainsKey(text)) { mDictionary[text] = value; return; } try { mDictionary.Add(text, value); } catch (Exception ex) { Debug.LogError("Unable to add '" + text + "' to the Localization dictionary.\n" + ex.Message); } } private static string[] ExtractStrings(BetterList added, string[] newLanguages, Dictionary languageIndices) { if (newLanguages == null) { string[] array = new string[mLanguages.Length]; int i = 1; for (int num = Mathf.Min(added.size, array.Length + 1); i < num; i++) { array[i - 1] = added[i]; } return array; } string key = added[0]; if (!mDictionary.TryGetValue(key, out var value)) { value = new string[mLanguages.Length]; } int j = 0; for (int num2 = newLanguages.Length; j < num2; j++) { string key2 = newLanguages[j]; int num3 = languageIndices[key2]; value[num3] = added[j + 1]; } return value; } private static bool SelectLanguage(string language) { mLanguageIndex = -1; if (mDictionary.Count == 0) { return false; } int i = 0; for (int num = mLanguages.Length; i < num; i++) { if (mLanguages[i] == language) { mOldDictionary.Clear(); mLanguageIndex = i; mLanguage = language; PlayerPrefs.SetString("Language", mLanguage); if (onLocalize != null) { onLocalize(); } UIRoot.Broadcast("OnLocalize"); return true; } } return false; } public static void Set(string languageName, Dictionary dictionary) { mLanguage = languageName; PlayerPrefs.SetString("Language", mLanguage); mOldDictionary = dictionary; localizationHasBeenSet = true; mLanguageIndex = -1; mLanguages = new string[1] { languageName }; if (onLocalize != null) { onLocalize(); } UIRoot.Broadcast("OnLocalize"); } public static void Set(string key, string value) { if (mOldDictionary.ContainsKey(key)) { mOldDictionary[key] = value; } else { mOldDictionary.Add(key, value); } } public static string Get(string key) { if (!localizationHasBeenSet) { LoadDictionary(PlayerPrefs.GetString("Language", "English")); } if (mLanguages == null) { Debug.LogError("No localization data present"); return null; } string text = language; if (mLanguageIndex == -1) { for (int i = 0; i < mLanguages.Length; i++) { if (mLanguages[i] == text) { mLanguageIndex = i; break; } } } if (mLanguageIndex == -1) { mLanguageIndex = 0; mLanguage = mLanguages[0]; } string value; string[] value2; switch (UICamera.currentScheme) { case UICamera.ControlScheme.Touch: { string key3 = key + " Mobile"; if (mReplacement.TryGetValue(key3, out value)) { return value; } if (mLanguageIndex != -1 && mDictionary.TryGetValue(key3, out value2) && mLanguageIndex < value2.Length) { return value2[mLanguageIndex]; } if (mOldDictionary.TryGetValue(key3, out value)) { return value; } break; } case UICamera.ControlScheme.Controller: { string key2 = key + " Controller"; if (mReplacement.TryGetValue(key2, out value)) { return value; } if (mLanguageIndex != -1 && mDictionary.TryGetValue(key2, out value2) && mLanguageIndex < value2.Length) { return value2[mLanguageIndex]; } if (mOldDictionary.TryGetValue(key2, out value)) { return value; } break; } } if (mReplacement.TryGetValue(key, out value)) { return value; } if (mLanguageIndex != -1 && mDictionary.TryGetValue(key, out value2)) { if (mLanguageIndex < value2.Length) { string text2 = value2[mLanguageIndex]; if (string.IsNullOrEmpty(text2)) { text2 = value2[0]; } return text2; } return value2[0]; } if (mOldDictionary.TryGetValue(key, out value)) { return value; } return key; } public static string Format(string key, params object[] parameters) { return string.Format(Get(key), parameters); } [Obsolete("Use Localization.Get instead")] public static string Localize(string key) { return Get(key); } public static bool Exists(string key) { if (!localizationHasBeenSet) { language = PlayerPrefs.GetString("Language", "English"); } if (!mDictionary.ContainsKey(key)) { return mOldDictionary.ContainsKey(key); } return true; } }