diff options
Diffstat (limited to 'Thronefall_v1.57/Thronefall/I2.Loc')
79 files changed, 11563 insertions, 0 deletions
diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ArabicMapping.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ArabicMapping.cs new file mode 100644 index 0000000..70b399e --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ArabicMapping.cs @@ -0,0 +1,14 @@ +namespace I2.Loc; + +internal class ArabicMapping +{ + public int from; + + public int to; + + public ArabicMapping(int from, int to) + { + this.from = from; + this.to = to; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ArabicTable.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ArabicTable.cs new file mode 100644 index 0000000..18db6a9 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ArabicTable.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; + +namespace I2.Loc; + +internal class ArabicTable +{ + private static List<ArabicMapping> mapList; + + private static ArabicTable arabicMapper; + + internal static ArabicTable ArabicMapper + { + get + { + if (arabicMapper == null) + { + arabicMapper = new ArabicTable(); + } + return arabicMapper; + } + } + + private ArabicTable() + { + mapList = new List<ArabicMapping>(); + mapList.Add(new ArabicMapping(1569, 65152)); + mapList.Add(new ArabicMapping(1575, 65165)); + mapList.Add(new ArabicMapping(1571, 65155)); + mapList.Add(new ArabicMapping(1572, 65157)); + mapList.Add(new ArabicMapping(1573, 65159)); + mapList.Add(new ArabicMapping(1609, 64508)); + mapList.Add(new ArabicMapping(1574, 65161)); + mapList.Add(new ArabicMapping(1576, 65167)); + mapList.Add(new ArabicMapping(1578, 65173)); + mapList.Add(new ArabicMapping(1579, 65177)); + mapList.Add(new ArabicMapping(1580, 65181)); + mapList.Add(new ArabicMapping(1581, 65185)); + mapList.Add(new ArabicMapping(1582, 65189)); + mapList.Add(new ArabicMapping(1583, 65193)); + mapList.Add(new ArabicMapping(1584, 65195)); + mapList.Add(new ArabicMapping(1585, 65197)); + mapList.Add(new ArabicMapping(1586, 65199)); + mapList.Add(new ArabicMapping(1587, 65201)); + mapList.Add(new ArabicMapping(1588, 65205)); + mapList.Add(new ArabicMapping(1589, 65209)); + mapList.Add(new ArabicMapping(1590, 65213)); + mapList.Add(new ArabicMapping(1591, 65217)); + mapList.Add(new ArabicMapping(1592, 65221)); + mapList.Add(new ArabicMapping(1593, 65225)); + mapList.Add(new ArabicMapping(1594, 65229)); + mapList.Add(new ArabicMapping(1601, 65233)); + mapList.Add(new ArabicMapping(1602, 65237)); + mapList.Add(new ArabicMapping(1603, 65241)); + mapList.Add(new ArabicMapping(1604, 65245)); + mapList.Add(new ArabicMapping(1605, 65249)); + mapList.Add(new ArabicMapping(1606, 65253)); + mapList.Add(new ArabicMapping(1607, 65257)); + mapList.Add(new ArabicMapping(1608, 65261)); + mapList.Add(new ArabicMapping(1610, 65265)); + mapList.Add(new ArabicMapping(1570, 65153)); + mapList.Add(new ArabicMapping(1577, 65171)); + mapList.Add(new ArabicMapping(1662, 64342)); + mapList.Add(new ArabicMapping(1670, 64378)); + mapList.Add(new ArabicMapping(1688, 64394)); + mapList.Add(new ArabicMapping(1711, 64402)); + mapList.Add(new ArabicMapping(1705, 64398)); + } + + internal int Convert(int toBeConverted) + { + foreach (ArabicMapping map in mapList) + { + if (map.from == toBeConverted) + { + return map.to; + } + } + return toBeConverted; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/AutoChangeCultureInfo.cs b/Thronefall_v1.57/Thronefall/I2.Loc/AutoChangeCultureInfo.cs new file mode 100644 index 0000000..569f62e --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/AutoChangeCultureInfo.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +namespace I2.Loc; + +public class AutoChangeCultureInfo : MonoBehaviour +{ + public void Start() + { + LocalizationManager.EnableChangingCultureInfo(bEnable: true); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/BaseSpecializationManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/BaseSpecializationManager.cs new file mode 100644 index 0000000..bb91640 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/BaseSpecializationManager.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; + +namespace I2.Loc; + +public class BaseSpecializationManager +{ + public string[] mSpecializations; + + public Dictionary<string, string> mSpecializationsFallbacks; + + public virtual void InitializeSpecializations() + { + mSpecializations = new string[12] + { + "Any", "PC", "Touch", "Controller", "VR", "XBox", "PS4", "OculusVR", "ViveVR", "GearVR", + "Android", "IOS" + }; + mSpecializationsFallbacks = new Dictionary<string, string>(StringComparer.Ordinal) + { + { "XBox", "Controller" }, + { "PS4", "Controller" }, + { "OculusVR", "VR" }, + { "ViveVR", "VR" }, + { "GearVR", "VR" }, + { "Android", "Touch" }, + { "IOS", "Touch" } + }; + } + + public virtual string GetCurrentSpecialization() + { + if (mSpecializations == null) + { + InitializeSpecializations(); + } + return "PC"; + } + + public virtual string GetFallbackSpecialization(string specialization) + { + if (mSpecializationsFallbacks == null) + { + InitializeSpecializations(); + } + if (mSpecializationsFallbacks.TryGetValue(specialization, out var value)) + { + return value; + } + return "Any"; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/CallbackNotification.cs b/Thronefall_v1.57/Thronefall/I2.Loc/CallbackNotification.cs new file mode 100644 index 0000000..7060292 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/CallbackNotification.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +namespace I2.Loc; + +public class CallbackNotification : MonoBehaviour +{ + public void OnModifyLocalization() + { + if (!string.IsNullOrEmpty(Localize.MainTranslation)) + { + string newValue = TextTranslator.Translate("Color/Red"); + Localize.MainTranslation = Localize.MainTranslation.Replace("{PLAYER_COLOR}", newValue); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/CoroutineManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/CoroutineManager.cs new file mode 100644 index 0000000..fa93b47 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/CoroutineManager.cs @@ -0,0 +1,40 @@ +using System.Collections; +using UnityEngine; + +namespace I2.Loc; + +public class CoroutineManager : MonoBehaviour +{ + private static CoroutineManager mInstance; + + private static CoroutineManager pInstance + { + get + { + if (mInstance == null) + { + GameObject gameObject = new GameObject("_Coroutiner"); + gameObject.hideFlags = HideFlags.HideAndDontSave; + mInstance = gameObject.AddComponent<CoroutineManager>(); + if (Application.isPlaying) + { + Object.DontDestroyOnLoad(gameObject); + } + } + return mInstance; + } + } + + private void Awake() + { + if (Application.isPlaying) + { + Object.DontDestroyOnLoad(base.gameObject); + } + } + + public static Coroutine Start(IEnumerator coroutine) + { + return pInstance.StartCoroutine(coroutine); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/CustomLocalizeCallback.cs b/Thronefall_v1.57/Thronefall/I2.Loc/CustomLocalizeCallback.cs new file mode 100644 index 0000000..d308920 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/CustomLocalizeCallback.cs @@ -0,0 +1,26 @@ +using UnityEngine; +using UnityEngine.Events; + +namespace I2.Loc; + +[AddComponentMenu("I2/Localization/I2 Localize Callback")] +public class CustomLocalizeCallback : MonoBehaviour +{ + public UnityEvent _OnLocalize = new UnityEvent(); + + public void OnEnable() + { + LocalizationManager.OnLocalizeEvent -= OnLocalize; + LocalizationManager.OnLocalizeEvent += OnLocalize; + } + + public void OnDisable() + { + LocalizationManager.OnLocalizeEvent -= OnLocalize; + } + + public void OnLocalize() + { + _OnLocalize.Invoke(); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/EventCallback.cs b/Thronefall_v1.57/Thronefall/I2.Loc/EventCallback.cs new file mode 100644 index 0000000..e0d63c6 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/EventCallback.cs @@ -0,0 +1,29 @@ +using System; +using UnityEngine; + +namespace I2.Loc; + +[Serializable] +public class EventCallback +{ + public MonoBehaviour Target; + + public string MethodName = string.Empty; + + public void Execute(UnityEngine.Object Sender = null) + { + if (HasCallback() && Application.isPlaying) + { + Target.gameObject.SendMessage(MethodName, Sender, SendMessageOptions.DontRequireReceiver); + } + } + + public bool HasCallback() + { + if (Target != null) + { + return !string.IsNullOrEmpty(MethodName); + } + return false; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/Example_ChangeLanguage.cs b/Thronefall_v1.57/Thronefall/I2.Loc/Example_ChangeLanguage.cs new file mode 100644 index 0000000..69819ad --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/Example_ChangeLanguage.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +namespace I2.Loc; + +public class Example_ChangeLanguage : MonoBehaviour +{ + public void SetLanguage_English() + { + SetLanguage("English"); + } + + public void SetLanguage_French() + { + SetLanguage("French"); + } + + public void SetLanguage_Spanish() + { + SetLanguage("Spanish"); + } + + public void SetLanguage(string LangName) + { + if (LocalizationManager.HasLanguage(LangName)) + { + LocalizationManager.CurrentLanguage = LangName; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/Example_LocalizedString.cs b/Thronefall_v1.57/Thronefall/I2.Loc/Example_LocalizedString.cs new file mode 100644 index 0000000..bd19bbb --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/Example_LocalizedString.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +namespace I2.Loc; + +public class Example_LocalizedString : MonoBehaviour +{ + public LocalizedString _MyLocalizedString; + + public string _NormalString; + + [TermsPopup("")] + public string _StringWithTermPopup; + + public void Start() + { + Debug.Log(_MyLocalizedString); + Debug.Log(TextTranslator.Translate(_NormalString)); + Debug.Log(TextTranslator.Translate(_StringWithTermPopup)); + Debug.Log((string)(LocalizedString)"Term2"); + Debug.Log(_MyLocalizedString); + Debug.Log((LocalizedString)"Term3"); + LocalizedString localizedString = "Term3"; + localizedString.mRTL_IgnoreArabicFix = true; + Debug.Log(localizedString); + LocalizedString localizedString2 = "Term3"; + localizedString2.mRTL_ConvertNumbers = true; + localizedString2.mRTL_MaxLineLength = 20; + Debug.Log(localizedString2); + Debug.Log(localizedString2); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/GeneralArabicLetters.cs b/Thronefall_v1.57/Thronefall/I2.Loc/GeneralArabicLetters.cs new file mode 100644 index 0000000..c6fecdd --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/GeneralArabicLetters.cs @@ -0,0 +1,46 @@ +namespace I2.Loc; + +internal enum GeneralArabicLetters +{ + Hamza = 1569, + Alef = 1575, + AlefHamza = 1571, + WawHamza = 1572, + AlefMaksoor = 1573, + AlefMagsora = 1609, + HamzaNabera = 1574, + Ba = 1576, + Ta = 1578, + Tha2 = 1579, + Jeem = 1580, + H7aa = 1581, + Khaa2 = 1582, + Dal = 1583, + Thal = 1584, + Ra2 = 1585, + Zeen = 1586, + Seen = 1587, + Sheen = 1588, + S9a = 1589, + Dha = 1590, + T6a = 1591, + T6ha = 1592, + Ain = 1593, + Gain = 1594, + Fa = 1601, + Gaf = 1602, + Kaf = 1603, + Lam = 1604, + Meem = 1605, + Noon = 1606, + Ha = 1607, + Waw = 1608, + Ya = 1610, + AlefMad = 1570, + TaMarboota = 1577, + PersianPe = 1662, + PersianChe = 1670, + PersianZe = 1688, + PersianGaf = 1711, + PersianGaf2 = 1705 +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/GlobalParametersExample.cs b/Thronefall_v1.57/Thronefall/I2.Loc/GlobalParametersExample.cs new file mode 100644 index 0000000..5b5a66c --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/GlobalParametersExample.cs @@ -0,0 +1,17 @@ +namespace I2.Loc; + +public class GlobalParametersExample : RegisterGlobalParameters +{ + public override string GetParameterValue(string ParamName) + { + if (ParamName == "WINNER") + { + return "Javier"; + } + if (ParamName == "NUM PLAYERS") + { + return 5.ToString(); + } + return null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/GoogleLanguages.cs b/Thronefall_v1.57/Thronefall/I2.Loc/GoogleLanguages.cs new file mode 100644 index 0000000..3157d04 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/GoogleLanguages.cs @@ -0,0 +1,2873 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace I2.Loc; + +public static class GoogleLanguages +{ + public struct LanguageCodeDef + { + public string Code; + + public string GoogleCode; + + public bool HasJoinedWords; + + public int PluralRule; + } + + public static Dictionary<string, LanguageCodeDef> mLanguageDef = new Dictionary<string, LanguageCodeDef>(StringComparer.Ordinal) + { + { + "Abkhazian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ab", + GoogleCode = "-" + } + }, + { + "Afar", + new LanguageCodeDef + { + PluralRule = 1, + Code = "aa", + GoogleCode = "-" + } + }, + { + "Afrikaans", + new LanguageCodeDef + { + PluralRule = 1, + Code = "af" + } + }, + { + "Akan", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ak", + GoogleCode = "-" + } + }, + { + "Albanian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sq" + } + }, + { + "Amharic", + new LanguageCodeDef + { + PluralRule = 1, + Code = "am" + } + }, + { + "Arabic", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar" + } + }, + { + "Arabic/Algeria", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-DZ", + GoogleCode = "ar" + } + }, + { + "Arabic/Bahrain", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-BH", + GoogleCode = "ar" + } + }, + { + "Arabic/Egypt", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-EG", + GoogleCode = "ar" + } + }, + { + "Arabic/Iraq", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-IQ", + GoogleCode = "ar" + } + }, + { + "Arabic/Jordan", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-JO", + GoogleCode = "ar" + } + }, + { + "Arabic/Kuwait", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-KW", + GoogleCode = "ar" + } + }, + { + "Arabic/Lebanon", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-LB", + GoogleCode = "ar" + } + }, + { + "Arabic/Libya", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-LY", + GoogleCode = "ar" + } + }, + { + "Arabic/Morocco", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-MA", + GoogleCode = "ar" + } + }, + { + "Arabic/Oman", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-OM", + GoogleCode = "ar" + } + }, + { + "Arabic/Qatar", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-QA", + GoogleCode = "ar" + } + }, + { + "Arabic/Saudi Arabia", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-SA", + GoogleCode = "ar" + } + }, + { + "Arabic/Syria", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-SY", + GoogleCode = "ar" + } + }, + { + "Arabic/Tunisia", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-TN", + GoogleCode = "ar" + } + }, + { + "Arabic/U.A.E.", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-AE", + GoogleCode = "ar" + } + }, + { + "Arabic/Yemen", + new LanguageCodeDef + { + PluralRule = 11, + Code = "ar-YE", + GoogleCode = "ar" + } + }, + { + "Aragonese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "an", + GoogleCode = "-" + } + }, + { + "Armenian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "hy" + } + }, + { + "Assamese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "as", + GoogleCode = "-" + } + }, + { + "Avaric", + new LanguageCodeDef + { + PluralRule = 1, + Code = "av", + GoogleCode = "-" + } + }, + { + "Avestan", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ae", + GoogleCode = "-" + } + }, + { + "Aymara", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ay", + GoogleCode = "-" + } + }, + { + "Azerbaijani", + new LanguageCodeDef + { + PluralRule = 1, + Code = "az" + } + }, + { + "Bambara", + new LanguageCodeDef + { + PluralRule = 1, + Code = "bm", + GoogleCode = "-" + } + }, + { + "Bashkir", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ba", + GoogleCode = "-" + } + }, + { + "Basque", + new LanguageCodeDef + { + PluralRule = 1, + Code = "eu" + } + }, + { + "Basque/Spain", + new LanguageCodeDef + { + PluralRule = 1, + Code = "eu-ES", + GoogleCode = "eu" + } + }, + { + "Belarusian", + new LanguageCodeDef + { + PluralRule = 6, + Code = "be" + } + }, + { + "Bengali", + new LanguageCodeDef + { + PluralRule = 1, + Code = "bn" + } + }, + { + "Bihari", + new LanguageCodeDef + { + PluralRule = 1, + Code = "bh", + GoogleCode = "-" + } + }, + { + "Bislama", + new LanguageCodeDef + { + PluralRule = 1, + Code = "bi", + GoogleCode = "-" + } + }, + { + "Bosnian", + new LanguageCodeDef + { + PluralRule = 6, + Code = "bs" + } + }, + { + "Breton", + new LanguageCodeDef + { + PluralRule = 1, + Code = "br", + GoogleCode = "-" + } + }, + { + "Bulgariaa", + new LanguageCodeDef + { + PluralRule = 1, + Code = "bg" + } + }, + { + "Burmese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "my" + } + }, + { + "Catalan", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ca" + } + }, + { + "Chamorro", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ch", + GoogleCode = "-" + } + }, + { + "Chechen", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ce", + GoogleCode = "-" + } + }, + { + "Chichewa", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ny" + } + }, + { + "Chinese", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh", + GoogleCode = "zh-CN", + HasJoinedWords = true + } + }, + { + "Chinese/Hong Kong", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh-HK", + GoogleCode = "zh-TW", + HasJoinedWords = true + } + }, + { + "Chinese/Macau", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh-MO", + GoogleCode = "zh-CN", + HasJoinedWords = true + } + }, + { + "Chinese/PRC", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh-CN", + GoogleCode = "zh-CN", + HasJoinedWords = true + } + }, + { + "Chinese/Simplified", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh-CN", + GoogleCode = "zh-CN", + HasJoinedWords = true + } + }, + { + "Chinese/Singapore", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh-SG", + GoogleCode = "zh-CN", + HasJoinedWords = true + } + }, + { + "Chinese/Taiwan", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh-TW", + GoogleCode = "zh-TW", + HasJoinedWords = true + } + }, + { + "Chinese/Traditional", + new LanguageCodeDef + { + PluralRule = 0, + Code = "zh-TW", + GoogleCode = "zh-TW", + HasJoinedWords = true + } + }, + { + "Chuvash", + new LanguageCodeDef + { + PluralRule = 1, + Code = "cv", + GoogleCode = "-" + } + }, + { + "Cornish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kw", + GoogleCode = "-" + } + }, + { + "Corsican", + new LanguageCodeDef + { + PluralRule = 1, + Code = "co" + } + }, + { + "Cree", + new LanguageCodeDef + { + PluralRule = 1, + Code = "cr", + GoogleCode = "-" + } + }, + { + "Croatian", + new LanguageCodeDef + { + PluralRule = 6, + Code = "hr" + } + }, + { + "Croatian/Bosnia and Herzegovina", + new LanguageCodeDef + { + PluralRule = 5, + Code = "hr-BA", + GoogleCode = "hr" + } + }, + { + "Czech", + new LanguageCodeDef + { + PluralRule = 7, + Code = "cs" + } + }, + { + "Danish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "da" + } + }, + { + "Divehi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "dv", + GoogleCode = "-" + } + }, + { + "Dutch", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nl" + } + }, + { + "Dutch/Belgium", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nl-BE", + GoogleCode = "nl" + } + }, + { + "Dutch/Netherlands", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nl-NL", + GoogleCode = "nl" + } + }, + { + "Dzongkha", + new LanguageCodeDef + { + PluralRule = 1, + Code = "dz", + GoogleCode = "-" + } + }, + { + "English", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en" + } + }, + { + "English/Australia", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-AU", + GoogleCode = "en" + } + }, + { + "English/Belize", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-BZ", + GoogleCode = "en" + } + }, + { + "English/Canada", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-CA", + GoogleCode = "en" + } + }, + { + "English/Caribbean", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-CB", + GoogleCode = "en" + } + }, + { + "English/Ireland", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-IE", + GoogleCode = "en" + } + }, + { + "English/Jamaica", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-JM", + GoogleCode = "en" + } + }, + { + "English/New Zealand", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-NZ", + GoogleCode = "en" + } + }, + { + "English/Republic of the Philippines", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-PH", + GoogleCode = "en" + } + }, + { + "English/South Africa", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-ZA", + GoogleCode = "en" + } + }, + { + "English/Trinidad", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-TT", + GoogleCode = "en" + } + }, + { + "English/United Kingdom", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-GB", + GoogleCode = "en" + } + }, + { + "English/United States", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-US", + GoogleCode = "en" + } + }, + { + "English/Zimbabwe", + new LanguageCodeDef + { + PluralRule = 1, + Code = "en-ZW", + GoogleCode = "en" + } + }, + { + "Esperanto", + new LanguageCodeDef + { + PluralRule = 1, + Code = "eo" + } + }, + { + "Estonian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "et" + } + }, + { + "Ewe", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ee", + GoogleCode = "-" + } + }, + { + "Faeroese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "fo", + GoogleCode = "-" + } + }, + { + "Fijian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "fj", + GoogleCode = "-" + } + }, + { + "Finnish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "fi" + } + }, + { + "French", + new LanguageCodeDef + { + PluralRule = 2, + Code = "fr" + } + }, + { + "French/Belgium", + new LanguageCodeDef + { + PluralRule = 2, + Code = "fr-BE", + GoogleCode = "fr" + } + }, + { + "French/Canada", + new LanguageCodeDef + { + PluralRule = 2, + Code = "fr-CA", + GoogleCode = "fr" + } + }, + { + "French/France", + new LanguageCodeDef + { + PluralRule = 2, + Code = "fr-FR", + GoogleCode = "fr" + } + }, + { + "French/Luxembourg", + new LanguageCodeDef + { + PluralRule = 2, + Code = "fr-LU", + GoogleCode = "fr" + } + }, + { + "French/Principality of Monaco", + new LanguageCodeDef + { + PluralRule = 2, + Code = "fr-MC", + GoogleCode = "fr" + } + }, + { + "French/Switzerland", + new LanguageCodeDef + { + PluralRule = 2, + Code = "fr-CH", + GoogleCode = "fr" + } + }, + { + "Fulah", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ff", + GoogleCode = "-" + } + }, + { + "Galician", + new LanguageCodeDef + { + PluralRule = 1, + Code = "gl" + } + }, + { + "Galician/Spain", + new LanguageCodeDef + { + PluralRule = 1, + Code = "gl-ES", + GoogleCode = "gl" + } + }, + { + "Georgian", + new LanguageCodeDef + { + PluralRule = 0, + Code = "ka" + } + }, + { + "German", + new LanguageCodeDef + { + PluralRule = 1, + Code = "de" + } + }, + { + "German/Austria", + new LanguageCodeDef + { + PluralRule = 1, + Code = "de-AT", + GoogleCode = "de" + } + }, + { + "German/Germany", + new LanguageCodeDef + { + PluralRule = 1, + Code = "de-DE", + GoogleCode = "de" + } + }, + { + "German/Liechtenstein", + new LanguageCodeDef + { + PluralRule = 1, + Code = "de-LI", + GoogleCode = "de" + } + }, + { + "German/Luxembourg", + new LanguageCodeDef + { + PluralRule = 1, + Code = "de-LU", + GoogleCode = "de" + } + }, + { + "German/Switzerland", + new LanguageCodeDef + { + PluralRule = 1, + Code = "de-CH", + GoogleCode = "de" + } + }, + { + "Greek", + new LanguageCodeDef + { + PluralRule = 1, + Code = "el" + } + }, + { + "Guaraní", + new LanguageCodeDef + { + PluralRule = 1, + Code = "gn", + GoogleCode = "-" + } + }, + { + "Gujarati", + new LanguageCodeDef + { + PluralRule = 1, + Code = "gu" + } + }, + { + "Haitian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ht" + } + }, + { + "Hausa", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ha" + } + }, + { + "Hebrew", + new LanguageCodeDef + { + PluralRule = 1, + Code = "he", + GoogleCode = "iw" + } + }, + { + "Herero", + new LanguageCodeDef + { + PluralRule = 1, + Code = "hz", + GoogleCode = "-" + } + }, + { + "Hindi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "hi" + } + }, + { + "Hiri Motu", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ho", + GoogleCode = "-" + } + }, + { + "Hungarian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "hu" + } + }, + { + "Interlingua", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ia", + GoogleCode = "-" + } + }, + { + "Indonesian", + new LanguageCodeDef + { + PluralRule = 0, + Code = "id" + } + }, + { + "Interlingue", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ie", + GoogleCode = "-" + } + }, + { + "Irish", + new LanguageCodeDef + { + PluralRule = 10, + Code = "ga" + } + }, + { + "Igbo", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ig" + } + }, + { + "Inupiaq", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ik", + GoogleCode = "-" + } + }, + { + "Ido", + new LanguageCodeDef + { + PluralRule = 1, + Code = "io", + GoogleCode = "-" + } + }, + { + "Icelandic", + new LanguageCodeDef + { + PluralRule = 14, + Code = "is" + } + }, + { + "Italian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "it" + } + }, + { + "Italian/Italy", + new LanguageCodeDef + { + PluralRule = 1, + Code = "it-IT", + GoogleCode = "it" + } + }, + { + "Italian/Switzerland", + new LanguageCodeDef + { + PluralRule = 1, + Code = "it-CH", + GoogleCode = "it" + } + }, + { + "Inuktitut", + new LanguageCodeDef + { + PluralRule = 1, + Code = "iu", + GoogleCode = "-" + } + }, + { + "Japanese", + new LanguageCodeDef + { + PluralRule = 0, + Code = "ja", + HasJoinedWords = true + } + }, + { + "Javanese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "jv" + } + }, + { + "Kalaallisut", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kl", + GoogleCode = "-" + } + }, + { + "Kannada", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kn" + } + }, + { + "Kanuri", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kr", + GoogleCode = "-" + } + }, + { + "Kashmiri", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ks", + GoogleCode = "-" + } + }, + { + "Kazakh", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kk" + } + }, + { + "Central Khmer", + new LanguageCodeDef + { + PluralRule = 1, + Code = "km" + } + }, + { + "Kikuyu", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ki", + GoogleCode = "-" + } + }, + { + "Kinyarwanda", + new LanguageCodeDef + { + PluralRule = 1, + Code = "rw", + GoogleCode = "-" + } + }, + { + "Kirghiz", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ky" + } + }, + { + "Komi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kv", + GoogleCode = "-" + } + }, + { + "Kongo", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kg", + GoogleCode = "-" + } + }, + { + "Korean", + new LanguageCodeDef + { + PluralRule = 0, + Code = "ko" + } + }, + { + "Kurdish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ku" + } + }, + { + "Kuanyama", + new LanguageCodeDef + { + PluralRule = 1, + Code = "kj", + GoogleCode = "-" + } + }, + { + "Latin", + new LanguageCodeDef + { + PluralRule = 1, + Code = "la" + } + }, + { + "Luxembourgish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "lb" + } + }, + { + "Ganda", + new LanguageCodeDef + { + PluralRule = 1, + Code = "lg", + GoogleCode = "-" + } + }, + { + "Limburgan", + new LanguageCodeDef + { + PluralRule = 1, + Code = "li", + GoogleCode = "-" + } + }, + { + "Lingala", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ln", + GoogleCode = "-" + } + }, + { + "Lao", + new LanguageCodeDef + { + PluralRule = 1, + Code = "lo" + } + }, + { + "Latvian", + new LanguageCodeDef + { + PluralRule = 5, + Code = "lv" + } + }, + { + "Luba-Katanga", + new LanguageCodeDef + { + PluralRule = 1, + Code = "lu", + GoogleCode = "-" + } + }, + { + "Lithuanian", + new LanguageCodeDef + { + PluralRule = 5, + Code = "lt" + } + }, + { + "Manx", + new LanguageCodeDef + { + PluralRule = 1, + Code = "gv", + GoogleCode = "-" + } + }, + { + "Macedonian", + new LanguageCodeDef + { + PluralRule = 13, + Code = "mk" + } + }, + { + "Malagasy", + new LanguageCodeDef + { + PluralRule = 1, + Code = "mg" + } + }, + { + "Malay", + new LanguageCodeDef + { + PluralRule = 0, + Code = "ms" + } + }, + { + "Malay/Brunei Darussalam", + new LanguageCodeDef + { + PluralRule = 0, + Code = "ms-BN", + GoogleCode = "ms" + } + }, + { + "Malay/Malaysia", + new LanguageCodeDef + { + PluralRule = 0, + Code = "ms-MY", + GoogleCode = "ms" + } + }, + { + "Malayalam", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ml" + } + }, + { + "Maltese", + new LanguageCodeDef + { + PluralRule = 12, + Code = "mt" + } + }, + { + "Maori", + new LanguageCodeDef + { + PluralRule = 2, + Code = "mi" + } + }, + { + "Marathi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "mr" + } + }, + { + "Marshallese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "mh", + GoogleCode = "-" + } + }, + { + "Mongolian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "mn" + } + }, + { + "Nauru", + new LanguageCodeDef + { + PluralRule = 1, + Code = "na", + GoogleCode = "-" + } + }, + { + "Navajo", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nv", + GoogleCode = "-" + } + }, + { + "North Ndebele", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nd", + GoogleCode = "-" + } + }, + { + "Nepali", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ne" + } + }, + { + "Ndonga", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ng", + GoogleCode = "-" + } + }, + { + "Northern Sotho", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ns", + GoogleCode = "st" + } + }, + { + "Norwegian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nb", + GoogleCode = "no" + } + }, + { + "Norwegian/Nynorsk", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nn", + GoogleCode = "no" + } + }, + { + "Sichuan Yi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ii", + GoogleCode = "-" + } + }, + { + "South Ndebele", + new LanguageCodeDef + { + PluralRule = 1, + Code = "nr", + GoogleCode = "-" + } + }, + { + "Occitan", + new LanguageCodeDef + { + PluralRule = 1, + Code = "oc", + GoogleCode = "-" + } + }, + { + "Ojibwa", + new LanguageCodeDef + { + PluralRule = 1, + Code = "oj", + GoogleCode = "-" + } + }, + { + "Church\u00a0Slavic", + new LanguageCodeDef + { + PluralRule = 1, + Code = "cu", + GoogleCode = "-" + } + }, + { + "Oromo", + new LanguageCodeDef + { + PluralRule = 1, + Code = "om", + GoogleCode = "-" + } + }, + { + "Oriya", + new LanguageCodeDef + { + PluralRule = 1, + Code = "or", + GoogleCode = "-" + } + }, + { + "Ossetian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "os", + GoogleCode = "-" + } + }, + { + "Pali", + new LanguageCodeDef + { + PluralRule = 1, + Code = "pi", + GoogleCode = "-" + } + }, + { + "Pashto", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ps" + } + }, + { + "Persian", + new LanguageCodeDef + { + PluralRule = 0, + Code = "fa" + } + }, + { + "Polish", + new LanguageCodeDef + { + PluralRule = 8, + Code = "pl" + } + }, + { + "Portuguese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "pt" + } + }, + { + "Portuguese/Brazil", + new LanguageCodeDef + { + PluralRule = 2, + Code = "pt-BR", + GoogleCode = "pt" + } + }, + { + "Portuguese/Portugal", + new LanguageCodeDef + { + PluralRule = 1, + Code = "pt-PT", + GoogleCode = "pt" + } + }, + { + "Punjabi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "pa" + } + }, + { + "Quechua", + new LanguageCodeDef + { + PluralRule = 1, + Code = "qu", + GoogleCode = "-" + } + }, + { + "Quechua/Bolivia", + new LanguageCodeDef + { + PluralRule = 1, + Code = "qu-BO", + GoogleCode = "-" + } + }, + { + "Quechua/Ecuador", + new LanguageCodeDef + { + PluralRule = 1, + Code = "qu-EC", + GoogleCode = "-" + } + }, + { + "Quechua/Peru", + new LanguageCodeDef + { + PluralRule = 1, + Code = "qu-PE", + GoogleCode = "-" + } + }, + { + "Rhaeto-Romanic", + new LanguageCodeDef + { + PluralRule = 1, + Code = "rm", + GoogleCode = "ro" + } + }, + { + "Romanian", + new LanguageCodeDef + { + PluralRule = 4, + Code = "ro" + } + }, + { + "Rundi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "rn", + GoogleCode = "-" + } + }, + { + "Russian", + new LanguageCodeDef + { + PluralRule = 6, + Code = "ru" + } + }, + { + "Russian/Republic of Moldova", + new LanguageCodeDef + { + PluralRule = 6, + Code = "ru-MO", + GoogleCode = "ru" + } + }, + { + "Sanskrit", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sa", + GoogleCode = "-" + } + }, + { + "Sardinian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sc", + GoogleCode = "-" + } + }, + { + "Sindhi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sd" + } + }, + { + "Northern Sami", + new LanguageCodeDef + { + PluralRule = 1, + Code = "se", + GoogleCode = "-" + } + }, + { + "Samoan", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sm" + } + }, + { + "Sango", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sg", + GoogleCode = "-" + } + }, + { + "Serbian", + new LanguageCodeDef + { + PluralRule = 6, + Code = "sr" + } + }, + { + "Serbian/Bosnia and Herzegovina", + new LanguageCodeDef + { + PluralRule = 5, + Code = "sr-BA", + GoogleCode = "sr" + } + }, + { + "Serbian/Serbia and Montenegro", + new LanguageCodeDef + { + PluralRule = 5, + Code = "sr-SP", + GoogleCode = "sr" + } + }, + { + "Scottish Gaelic", + new LanguageCodeDef + { + PluralRule = 1, + Code = "gd" + } + }, + { + "Shona", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sn" + } + }, + { + "Sinhala", + new LanguageCodeDef + { + PluralRule = 1, + Code = "si" + } + }, + { + "Slovak", + new LanguageCodeDef + { + PluralRule = 7, + Code = "sk" + } + }, + { + "Slovenian", + new LanguageCodeDef + { + PluralRule = 9, + Code = "sl" + } + }, + { + "Somali", + new LanguageCodeDef + { + PluralRule = 1, + Code = "so" + } + }, + { + "Southern Sotho", + new LanguageCodeDef + { + PluralRule = 1, + Code = "st" + } + }, + { + "Spanish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es" + } + }, + { + "Spanish/Argentina", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-AR", + GoogleCode = "es" + } + }, + { + "Spanish/Bolivia", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-BO", + GoogleCode = "es" + } + }, + { + "Spanish/Castilian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-ES", + GoogleCode = "es" + } + }, + { + "Spanish/Chile", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-CL", + GoogleCode = "es" + } + }, + { + "Spanish/Colombia", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-CO", + GoogleCode = "es" + } + }, + { + "Spanish/Costa Rica", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-CR", + GoogleCode = "es" + } + }, + { + "Spanish/Dominican Republic", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-DO", + GoogleCode = "es" + } + }, + { + "Spanish/Ecuador", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-EC", + GoogleCode = "es" + } + }, + { + "Spanish/El Salvador", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-SV", + GoogleCode = "es" + } + }, + { + "Spanish/Guatemala", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-GT", + GoogleCode = "es" + } + }, + { + "Spanish/Honduras", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-HN", + GoogleCode = "es" + } + }, + { + "Spanish/Mexico", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-MX", + GoogleCode = "es" + } + }, + { + "Spanish/Nicaragua", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-NI", + GoogleCode = "es" + } + }, + { + "Spanish/Panama", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-PA", + GoogleCode = "es" + } + }, + { + "Spanish/Paraguay", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-PY", + GoogleCode = "es" + } + }, + { + "Spanish/Peru", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-PE", + GoogleCode = "es" + } + }, + { + "Spanish/Puerto Rico", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-PR", + GoogleCode = "es" + } + }, + { + "Spanish/Spain", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-ES", + GoogleCode = "es" + } + }, + { + "Spanish/Uruguay", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-UY", + GoogleCode = "es" + } + }, + { + "Spanish/Venezuela", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-VE", + GoogleCode = "es" + } + }, + { + "Spanish/Latin Americas", + new LanguageCodeDef + { + PluralRule = 1, + Code = "es-US", + GoogleCode = "es" + } + }, + { + "Sundanese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "su" + } + }, + { + "Swahili", + new LanguageCodeDef + { + Code = "sw" + } + }, + { + "Swati", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ss", + GoogleCode = "-" + } + }, + { + "Swedish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sv" + } + }, + { + "Swedish/Finland", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sv-FI", + GoogleCode = "sv" + } + }, + { + "Swedish/Sweden", + new LanguageCodeDef + { + PluralRule = 1, + Code = "sv-SE", + GoogleCode = "sv" + } + }, + { + "Tamil", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ta" + } + }, + { + "Tatar", + new LanguageCodeDef + { + PluralRule = 0, + Code = "tt", + GoogleCode = "-" + } + }, + { + "Telugu", + new LanguageCodeDef + { + PluralRule = 1, + Code = "te" + } + }, + { + "Tajik", + new LanguageCodeDef + { + PluralRule = 1, + Code = "tg" + } + }, + { + "Thai", + new LanguageCodeDef + { + PluralRule = 0, + Code = "th", + HasJoinedWords = true + } + }, + { + "Tigrinya", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ti", + GoogleCode = "-" + } + }, + { + "Tibetan", + new LanguageCodeDef + { + PluralRule = 1, + Code = "bo", + GoogleCode = "-" + } + }, + { + "Turkmen", + new LanguageCodeDef + { + PluralRule = 1, + Code = "tk", + GoogleCode = "-" + } + }, + { + "Tagalog", + new LanguageCodeDef + { + PluralRule = 1, + Code = "tl" + } + }, + { + "Tswana", + new LanguageCodeDef + { + PluralRule = 1, + Code = "tn", + GoogleCode = "-" + } + }, + { + "Tonga", + new LanguageCodeDef + { + PluralRule = 1, + Code = "to", + GoogleCode = "-" + } + }, + { + "Turkish", + new LanguageCodeDef + { + PluralRule = 0, + Code = "tr" + } + }, + { + "Tsonga", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ts", + GoogleCode = "-" + } + }, + { + "Twi", + new LanguageCodeDef + { + PluralRule = 1, + Code = "tw", + GoogleCode = "-" + } + }, + { + "Tahitian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ty", + GoogleCode = "-" + } + }, + { + "Uighur", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ug", + GoogleCode = "-" + } + }, + { + "Ukrainian", + new LanguageCodeDef + { + PluralRule = 6, + Code = "uk" + } + }, + { + "Urdu", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ur" + } + }, + { + "Uzbek", + new LanguageCodeDef + { + PluralRule = 2, + Code = "uz" + } + }, + { + "Venda", + new LanguageCodeDef + { + PluralRule = 1, + Code = "ve", + GoogleCode = "-" + } + }, + { + "Vietnamese", + new LanguageCodeDef + { + PluralRule = 1, + Code = "vi" + } + }, + { + "Volapük", + new LanguageCodeDef + { + PluralRule = 1, + Code = "vo", + GoogleCode = "-" + } + }, + { + "Walloon", + new LanguageCodeDef + { + PluralRule = 1, + Code = "wa", + GoogleCode = "-" + } + }, + { + "Welsh", + new LanguageCodeDef + { + PluralRule = 16, + Code = "cy" + } + }, + { + "Wolof", + new LanguageCodeDef + { + PluralRule = 1, + Code = "wo", + GoogleCode = "-" + } + }, + { + "Frisian", + new LanguageCodeDef + { + PluralRule = 1, + Code = "fy" + } + }, + { + "Xhosa", + new LanguageCodeDef + { + PluralRule = 1, + Code = "xh" + } + }, + { + "Yiddish", + new LanguageCodeDef + { + PluralRule = 1, + Code = "yi" + } + }, + { + "Yoruba", + new LanguageCodeDef + { + PluralRule = 1, + Code = "yo" + } + }, + { + "Zhuang", + new LanguageCodeDef + { + PluralRule = 1, + Code = "za", + GoogleCode = "-" + } + }, + { + "Zulu", + new LanguageCodeDef + { + PluralRule = 1, + Code = "zu" + } + } + }; + + public static string GetLanguageCode(string Filter, bool ShowWarnings = false) + { + if (string.IsNullOrEmpty(Filter)) + { + return string.Empty; + } + string[] filters = Filter.ToLowerInvariant().Split(" /(),".ToCharArray()); + foreach (KeyValuePair<string, LanguageCodeDef> item in mLanguageDef) + { + if (LanguageMatchesFilter(item.Key, filters)) + { + return item.Value.Code; + } + } + if (ShowWarnings) + { + Debug.Log("Language '" + Filter + "' not recognized. Please, add the language code to GoogleTranslation.cs"); + } + return string.Empty; + } + + public static List<string> GetLanguagesForDropdown(string Filter, string CodesToExclude) + { + string[] filters = Filter.ToLowerInvariant().Split(" /(),".ToCharArray()); + List<string> list = new List<string>(); + foreach (KeyValuePair<string, LanguageCodeDef> item in mLanguageDef) + { + if (string.IsNullOrEmpty(Filter) || LanguageMatchesFilter(item.Key, filters)) + { + string text = string.Concat("[" + item.Value.Code + "]"); + if (!CodesToExclude.Contains(text)) + { + list.Add(item.Key + " " + text); + } + } + } + for (int num = list.Count - 2; num >= 0; num--) + { + string text2 = list[num].Substring(0, list[num].IndexOf(" [")); + if (list[num + 1].StartsWith(text2, StringComparison.Ordinal)) + { + list[num] = text2 + "/" + list[num]; + list.Insert(num + 1, text2 + "/"); + } + } + return list; + } + + private static bool LanguageMatchesFilter(string Language, string[] Filters) + { + Language = Language.ToLowerInvariant(); + int i = 0; + for (int num = Filters.Length; i < num; i++) + { + if (Filters[i] != "") + { + if (!Language.Contains(Filters[i].ToLower())) + { + return false; + } + Language = Language.Remove(Language.IndexOf(Filters[i], StringComparison.Ordinal), Filters[i].Length); + } + } + return true; + } + + public static string GetFormatedLanguageName(string Language) + { + string empty = string.Empty; + int num = Language.IndexOf(" [", StringComparison.Ordinal); + if (num > 0) + { + Language = Language.Substring(0, num); + } + num = Language.IndexOf('/'); + if (num > 0) + { + empty = Language.Substring(0, num); + if (Language == empty + "/" + empty) + { + return empty; + } + Language = Language.Replace("/", " (") + ")"; + } + return Language; + } + + public static string GetCodedLanguage(string Language, string code) + { + string languageCode = GetLanguageCode(Language); + if (string.Compare(code, languageCode, StringComparison.OrdinalIgnoreCase) == 0) + { + return Language; + } + return Language + " [" + code + "]"; + } + + public static void UnPackCodeFromLanguageName(string CodedLanguage, out string Language, out string code) + { + if (string.IsNullOrEmpty(CodedLanguage)) + { + Language = string.Empty; + code = string.Empty; + return; + } + int num = CodedLanguage.IndexOf("[", StringComparison.Ordinal); + if (num < 0) + { + Language = CodedLanguage; + code = GetLanguageCode(Language); + } + else + { + Language = CodedLanguage.Substring(0, num).Trim(); + code = CodedLanguage.Substring(num + 1, CodedLanguage.IndexOf("]", num, StringComparison.Ordinal) - num - 1); + } + } + + public static string GetGoogleLanguageCode(string InternationalCode) + { + foreach (KeyValuePair<string, LanguageCodeDef> item in mLanguageDef) + { + if (InternationalCode == item.Value.Code) + { + if (item.Value.GoogleCode == "-") + { + return null; + } + return (!string.IsNullOrEmpty(item.Value.GoogleCode)) ? item.Value.GoogleCode : InternationalCode; + } + } + return InternationalCode; + } + + public static string GetLanguageName(string code, bool useParenthesesForRegion = false, bool allowDiscardRegion = true) + { + foreach (KeyValuePair<string, LanguageCodeDef> item in mLanguageDef) + { + if (!(code == item.Value.Code)) + { + continue; + } + string text = item.Key; + if (useParenthesesForRegion) + { + int num = text.IndexOf('/'); + if (num > 0) + { + text = text.Substring(0, num) + " (" + text.Substring(num + 1) + ")"; + } + } + return text; + } + if (allowDiscardRegion) + { + int num2 = code.IndexOf("-", StringComparison.Ordinal); + if (num2 > 0) + { + return GetLanguageName(code.Substring(0, num2), useParenthesesForRegion, allowDiscardRegion: false); + } + } + return null; + } + + public static List<string> GetAllInternationalCodes() + { + HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); + foreach (KeyValuePair<string, LanguageCodeDef> item in mLanguageDef) + { + hashSet.Add(item.Value.Code); + } + return new List<string>(hashSet); + } + + public static bool LanguageCode_HasJoinedWord(string languageCode) + { + foreach (KeyValuePair<string, LanguageCodeDef> item in mLanguageDef) + { + if (languageCode == item.Value.GoogleCode || languageCode == item.Value.Code) + { + return item.Value.HasJoinedWords; + } + } + return false; + } + + private static int GetPluralRule(string langCode) + { + if (langCode.Length > 2) + { + langCode = langCode.Substring(0, 2); + } + langCode = langCode.ToLower(); + foreach (KeyValuePair<string, LanguageCodeDef> item in mLanguageDef) + { + if (item.Value.Code == langCode) + { + return item.Value.PluralRule; + } + } + return 0; + } + + public static bool LanguageHasPluralType(string langCode, string pluralType) + { + switch (pluralType) + { + case "Plural": + case "Zero": + case "One": + return true; + default: + switch (GetPluralRule(langCode)) + { + case 3: + if (!(pluralType == "Two")) + { + return pluralType == "Few"; + } + return true; + case 4: + case 5: + case 6: + case 7: + case 8: + return pluralType == "Few"; + case 9: + if (!(pluralType == "Two")) + { + return pluralType == "Few"; + } + return true; + case 10: + case 11: + case 15: + case 16: + if (!(pluralType == "Two") && !(pluralType == "Few")) + { + return pluralType == "Many"; + } + return true; + case 12: + if (!(pluralType == "Few")) + { + return pluralType == "Many"; + } + return true; + case 13: + return pluralType == "Two"; + default: + return false; + } + } + } + + public static ePluralType GetPluralType(string langCode, int n) + { + switch (n) + { + case 0: + return ePluralType.Zero; + case 1: + return ePluralType.One; + default: + switch (GetPluralRule(langCode)) + { + case 0: + return ePluralType.Plural; + case 1: + if (n != 1) + { + return ePluralType.Plural; + } + return ePluralType.One; + case 2: + if (n > 1) + { + return ePluralType.Plural; + } + return ePluralType.One; + case 3: + switch (n) + { + default: + if (!inRange(n, 3, 10) && !inRange(n, 13, 19)) + { + return ePluralType.Plural; + } + return ePluralType.Few; + case 2: + case 12: + return ePluralType.Two; + case 1: + case 11: + return ePluralType.One; + } + case 4: + if (n != 1) + { + if (!inRange(n % 100, 1, 19)) + { + return ePluralType.Plural; + } + return ePluralType.Few; + } + return ePluralType.One; + case 5: + if (n % 10 != 1 || n % 100 == 11) + { + if (n % 10 < 2 || (n % 100 >= 10 && n % 100 < 20)) + { + return ePluralType.Plural; + } + return ePluralType.Few; + } + return ePluralType.One; + case 6: + if (n % 10 != 1 || n % 100 == 11) + { + if (!inRange(n % 10, 2, 4) || inRange(n % 100, 12, 14)) + { + return ePluralType.Plural; + } + return ePluralType.Few; + } + return ePluralType.One; + case 7: + if (n != 1) + { + if (!inRange(n, 2, 4)) + { + return ePluralType.Plural; + } + return ePluralType.Few; + } + return ePluralType.One; + case 8: + if (n != 1) + { + if (!inRange(n % 10, 2, 4) || inRange(n % 100, 12, 14)) + { + return ePluralType.Plural; + } + return ePluralType.Few; + } + return ePluralType.One; + case 9: + if (n % 100 != 1) + { + if (n % 100 != 2) + { + if (!inRange(n % 100, 3, 4)) + { + return ePluralType.Plural; + } + return ePluralType.Few; + } + return ePluralType.Two; + } + return ePluralType.One; + case 10: + switch (n) + { + default: + if (!inRange(n, 3, 6)) + { + if (!inRange(n, 7, 10)) + { + return ePluralType.Plural; + } + return ePluralType.Many; + } + return ePluralType.Few; + case 2: + return ePluralType.Two; + case 1: + return ePluralType.One; + } + case 11: + switch (n) + { + default: + if (!inRange(n % 100, 3, 10)) + { + if (n % 100 < 11) + { + return ePluralType.Plural; + } + return ePluralType.Many; + } + return ePluralType.Few; + case 2: + return ePluralType.Two; + case 1: + return ePluralType.One; + case 0: + return ePluralType.Zero; + } + case 12: + if (n != 1) + { + if (!inRange(n % 100, 1, 10)) + { + if (!inRange(n % 100, 11, 19)) + { + return ePluralType.Plural; + } + return ePluralType.Many; + } + return ePluralType.Few; + } + return ePluralType.One; + case 13: + if (n % 10 != 1) + { + if (n % 10 != 2) + { + return ePluralType.Plural; + } + return ePluralType.Two; + } + return ePluralType.One; + case 14: + if (n % 10 != 1 || n % 100 == 11) + { + return ePluralType.Plural; + } + return ePluralType.One; + case 15: + if (n % 10 != 1 || n % 100 == 11 || n % 100 == 71 || n % 100 == 91) + { + if (n % 10 != 2 || n % 100 == 12 || n % 100 == 72 || n % 100 == 92) + { + if ((n % 10 != 3 && n % 10 != 4 && n % 10 != 9) || n % 100 == 13 || n % 100 == 14 || n % 100 == 19 || n % 100 == 73 || n % 100 == 74 || n % 100 == 79 || n % 100 == 93 || n % 100 == 94 || n % 100 == 99) + { + if (n % 1000000 != 0) + { + return ePluralType.Plural; + } + return ePluralType.Many; + } + return ePluralType.Few; + } + return ePluralType.Two; + } + return ePluralType.One; + case 16: + return n switch + { + 6 => ePluralType.Many, + 3 => ePluralType.Few, + 2 => ePluralType.Two, + 1 => ePluralType.One, + 0 => ePluralType.Zero, + _ => ePluralType.Plural, + }; + default: + return ePluralType.Plural; + } + } + } + + public static int GetPluralTestNumber(string langCode, ePluralType pluralType) + { + switch (pluralType) + { + case ePluralType.Zero: + return 0; + case ePluralType.One: + return 1; + case ePluralType.Few: + return 3; + case ePluralType.Many: + switch (GetPluralRule(langCode)) + { + case 10: + return 8; + case 11: + case 12: + return 13; + case 15: + return 1000000; + default: + return 6; + } + default: + return 936; + } + } + + private static bool inRange(int amount, int min, int max) + { + if (amount >= min) + { + return amount <= max; + } + return false; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/GoogleTranslation.cs b/Thronefall_v1.57/Thronefall/I2.Loc/GoogleTranslation.cs new file mode 100644 index 0000000..94f3869 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/GoogleTranslation.cs @@ -0,0 +1,575 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using UnityEngine.Networking; + +namespace I2.Loc; + +public static class GoogleTranslation +{ + public delegate void fnOnTranslated(string Translation, string Error); + + public delegate void fnOnTranslationReady(Dictionary<string, TranslationQuery> dict, string error); + + private static List<UnityWebRequest> mCurrentTranslations = new List<UnityWebRequest>(); + + private static List<TranslationJob> mTranslationJobs = new List<TranslationJob>(); + + public static bool CanTranslate() + { + if (LocalizationManager.Sources.Count > 0) + { + return !string.IsNullOrEmpty(LocalizationManager.GetWebServiceURL()); + } + return false; + } + + public static void Translate(string text, string LanguageCodeFrom, string LanguageCodeTo, fnOnTranslated OnTranslationReady) + { + LocalizationManager.InitializeIfNeeded(); + if (!CanTranslate()) + { + OnTranslationReady(null, "WebService is not set correctly or needs to be reinstalled"); + return; + } + if (LanguageCodeTo == LanguageCodeFrom) + { + OnTranslationReady(text, null); + return; + } + Dictionary<string, TranslationQuery> queries = new Dictionary<string, TranslationQuery>(StringComparer.Ordinal); + if (string.IsNullOrEmpty(LanguageCodeTo)) + { + OnTranslationReady(string.Empty, null); + return; + } + CreateQueries(text, LanguageCodeFrom, LanguageCodeTo, queries); + Translate(queries, delegate(Dictionary<string, TranslationQuery> results, string error) + { + if (!string.IsNullOrEmpty(error) || results.Count == 0) + { + OnTranslationReady(null, error); + } + else + { + string translation = RebuildTranslation(text, queries, LanguageCodeTo); + OnTranslationReady(translation, null); + } + }); + } + + public static string ForceTranslate(string text, string LanguageCodeFrom, string LanguageCodeTo) + { + Dictionary<string, TranslationQuery> dictionary = new Dictionary<string, TranslationQuery>(StringComparer.Ordinal); + AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dictionary); + TranslationJob_Main translationJob_Main = new TranslationJob_Main(dictionary, null); + while (true) + { + switch (translationJob_Main.GetState()) + { + case TranslationJob.eJobState.Running: + break; + case TranslationJob.eJobState.Failed: + return null; + default: + return GetQueryResult(text, "", dictionary); + } + } + } + + public static void Translate(Dictionary<string, TranslationQuery> requests, fnOnTranslationReady OnTranslationReady, bool usePOST = true) + { + AddTranslationJob(new TranslationJob_Main(requests, OnTranslationReady)); + } + + public static bool ForceTranslate(Dictionary<string, TranslationQuery> requests, bool usePOST = true) + { + TranslationJob_Main translationJob_Main = new TranslationJob_Main(requests, null); + while (true) + { + switch (translationJob_Main.GetState()) + { + case TranslationJob.eJobState.Running: + break; + case TranslationJob.eJobState.Failed: + return false; + default: + return true; + } + } + } + + public static List<string> ConvertTranslationRequest(Dictionary<string, TranslationQuery> requests, bool encodeGET) + { + List<string> list = new List<string>(); + StringBuilder stringBuilder = new StringBuilder(); + foreach (KeyValuePair<string, TranslationQuery> request in requests) + { + TranslationQuery value = request.Value; + if (stringBuilder.Length > 0) + { + stringBuilder.Append("<I2Loc>"); + } + stringBuilder.Append(GoogleLanguages.GetGoogleLanguageCode(value.LanguageCode)); + stringBuilder.Append(":"); + for (int i = 0; i < value.TargetLanguagesCode.Length; i++) + { + if (i != 0) + { + stringBuilder.Append(","); + } + stringBuilder.Append(GoogleLanguages.GetGoogleLanguageCode(value.TargetLanguagesCode[i])); + } + stringBuilder.Append("="); + string text = ((TitleCase(value.Text) == value.Text) ? value.Text.ToLowerInvariant() : value.Text); + if (!encodeGET) + { + stringBuilder.Append(text); + continue; + } + stringBuilder.Append(Uri.EscapeDataString(text)); + if (stringBuilder.Length > 4000) + { + list.Add(stringBuilder.ToString()); + stringBuilder.Length = 0; + } + } + list.Add(stringBuilder.ToString()); + return list; + } + + private static void AddTranslationJob(TranslationJob job) + { + mTranslationJobs.Add(job); + if (mTranslationJobs.Count == 1) + { + CoroutineManager.Start(WaitForTranslations()); + } + } + + private static IEnumerator WaitForTranslations() + { + while (mTranslationJobs.Count > 0) + { + TranslationJob[] array = mTranslationJobs.ToArray(); + foreach (TranslationJob translationJob in array) + { + if (translationJob.GetState() != 0) + { + mTranslationJobs.Remove(translationJob); + } + } + yield return null; + } + } + + public static string ParseTranslationResult(string html, Dictionary<string, TranslationQuery> requests) + { + if (html.StartsWith("<!DOCTYPE html>") || html.StartsWith("<HTML>")) + { + if (html.Contains("The script completed but did not return anything")) + { + return "The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version."; + } + if (html.Contains("Service invoked too many times in a short time")) + { + return ""; + } + return "There was a problem contacting the WebService. Please try again later\n" + html; + } + string[] array = html.Split(new string[1] { "<I2Loc>" }, StringSplitOptions.None); + string[] separator = new string[1] { "<i2>" }; + int num = 0; + string[] array2 = requests.Keys.ToArray(); + foreach (string text in array2) + { + TranslationQuery value = FindQueryFromOrigText(text, requests); + string text2 = array[num++]; + if (value.Tags != null) + { + for (int num2 = value.Tags.Length - 1; num2 >= 0; num2--) + { + text2 = text2.Replace(GetGoogleNoTranslateTag(num2), value.Tags[num2]); + } + } + value.Results = text2.Split(separator, StringSplitOptions.None); + if (TitleCase(text) == text) + { + for (int j = 0; j < value.Results.Length; j++) + { + value.Results[j] = TitleCase(value.Results[j]); + } + } + requests[value.OrigText] = value; + } + return null; + } + + public static bool IsTranslating() + { + if (mCurrentTranslations.Count <= 0) + { + return mTranslationJobs.Count > 0; + } + return true; + } + + public static void CancelCurrentGoogleTranslations() + { + mCurrentTranslations.Clear(); + foreach (TranslationJob mTranslationJob in mTranslationJobs) + { + mTranslationJob.Dispose(); + } + mTranslationJobs.Clear(); + } + + public static void CreateQueries(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict) + { + if (!text.Contains("[i2s_")) + { + CreateQueries_Plurals(text, LanguageCodeFrom, LanguageCodeTo, dict); + return; + } + foreach (KeyValuePair<string, string> specialization in SpecializationManager.GetSpecializations(text)) + { + CreateQueries_Plurals(specialization.Value, LanguageCodeFrom, LanguageCodeTo, dict); + } + } + + private static void CreateQueries_Plurals(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict) + { + bool flag = text.Contains("{[#"); + bool flag2 = text.Contains("[i2p_"); + if (!HasParameters(text) || (!flag && !flag2)) + { + AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dict); + return; + } + bool forceTag = flag; + for (ePluralType ePluralType2 = ePluralType.Zero; ePluralType2 <= ePluralType.Plural; ePluralType2++) + { + string pluralType = ePluralType2.ToString(); + if (GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, pluralType)) + { + string text2 = GetPluralText(text, pluralType); + int pluralTestNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, ePluralType2); + string pluralParameter = GetPluralParameter(text2, forceTag); + if (!string.IsNullOrEmpty(pluralParameter)) + { + text2 = text2.Replace(pluralParameter, pluralTestNumber.ToString()); + } + AddQuery(text2, LanguageCodeFrom, LanguageCodeTo, dict); + } + } + } + + public static void AddQuery(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict) + { + if (string.IsNullOrEmpty(text)) + { + return; + } + if (!dict.ContainsKey(text)) + { + TranslationQuery translationQuery = default(TranslationQuery); + translationQuery.OrigText = text; + translationQuery.LanguageCode = LanguageCodeFrom; + translationQuery.TargetLanguagesCode = new string[1] { LanguageCodeTo }; + TranslationQuery query = translationQuery; + query.Text = text; + ParseNonTranslatableElements(ref query); + dict[text] = query; + } + else + { + TranslationQuery value = dict[text]; + if (Array.IndexOf(value.TargetLanguagesCode, LanguageCodeTo) < 0) + { + value.TargetLanguagesCode = value.TargetLanguagesCode.Concat(new string[1] { LanguageCodeTo }).Distinct().ToArray(); + } + dict[text] = value; + } + } + + private static string GetTranslation(string text, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict) + { + if (!dict.ContainsKey(text)) + { + return null; + } + TranslationQuery translationQuery = dict[text]; + int num = Array.IndexOf(translationQuery.TargetLanguagesCode, LanguageCodeTo); + if (num < 0) + { + return ""; + } + if (translationQuery.Results == null) + { + return ""; + } + return translationQuery.Results[num]; + } + + private static TranslationQuery FindQueryFromOrigText(string origText, Dictionary<string, TranslationQuery> dict) + { + foreach (KeyValuePair<string, TranslationQuery> item in dict) + { + if (item.Value.OrigText == origText) + { + return item.Value; + } + } + return default(TranslationQuery); + } + + public static bool HasParameters(string text) + { + int num = text.IndexOf("{[", StringComparison.Ordinal); + if (num < 0) + { + return false; + } + return text.IndexOf("]}", num, StringComparison.Ordinal) > 0; + } + + public static string GetPluralParameter(string text, bool forceTag) + { + int num = text.IndexOf("{[#", StringComparison.Ordinal); + if (num < 0) + { + if (forceTag) + { + return null; + } + num = text.IndexOf("{[", StringComparison.Ordinal); + } + if (num < 0) + { + return null; + } + int num2 = text.IndexOf("]}", num + 2, StringComparison.Ordinal); + if (num2 < 0) + { + return null; + } + return text.Substring(num, num2 - num + 2); + } + + public static string GetPluralText(string text, string pluralType) + { + pluralType = "[i2p_" + pluralType + "]"; + int num = text.IndexOf(pluralType, StringComparison.Ordinal); + if (num >= 0) + { + num += pluralType.Length; + int num2 = text.IndexOf("[i2p_", num, StringComparison.Ordinal); + if (num2 < 0) + { + num2 = text.Length; + } + return text.Substring(num, num2 - num); + } + num = text.IndexOf("[i2p_", StringComparison.Ordinal); + if (num < 0) + { + return text; + } + if (num > 0) + { + return text.Substring(0, num); + } + num = text.IndexOf("]", StringComparison.Ordinal); + if (num < 0) + { + return text; + } + num++; + int num3 = text.IndexOf("[i2p_", num, StringComparison.Ordinal); + if (num3 < 0) + { + num3 = text.Length; + } + return text.Substring(num, num3 - num); + } + + private static int FindClosingTag(string tag, MatchCollection matches, int startIndex) + { + int i = startIndex; + for (int count = matches.Count; i < count; i++) + { + string captureMatch = I2Utils.GetCaptureMatch(matches[i]); + if (captureMatch[0] == '/' && tag.StartsWith(captureMatch.Substring(1), StringComparison.Ordinal)) + { + return i; + } + } + return -1; + } + + private static string GetGoogleNoTranslateTag(int tagNumber) + { + if (tagNumber < 70) + { + return "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++".Substring(0, tagNumber + 1); + } + string text = ""; + for (int i = -1; i < tagNumber; i++) + { + text += "+"; + } + return text; + } + + private static void ParseNonTranslatableElements(ref TranslationQuery query) + { + MatchCollection matchCollection = Regex.Matches(query.Text, "\\{\\[(.*?)]}|\\[(.*?)]|\\<(.*?)>"); + if (matchCollection == null || matchCollection.Count == 0) + { + return; + } + string text = query.Text; + List<string> list = new List<string>(); + int i = 0; + for (int count = matchCollection.Count; i < count; i++) + { + string captureMatch = I2Utils.GetCaptureMatch(matchCollection[i]); + int num = FindClosingTag(captureMatch, matchCollection, i); + if (num < 0) + { + string text2 = matchCollection[i].ToString(); + if (text2.StartsWith("{[", StringComparison.Ordinal) && text2.EndsWith("]}", StringComparison.Ordinal)) + { + text = text.Replace(text2, GetGoogleNoTranslateTag(list.Count) + " "); + list.Add(text2); + } + } + else if (captureMatch == "i2nt") + { + string text3 = query.Text.Substring(matchCollection[i].Index, matchCollection[num].Index - matchCollection[i].Index + matchCollection[num].Length); + text = text.Replace(text3, GetGoogleNoTranslateTag(list.Count) + " "); + list.Add(text3); + } + else + { + string text4 = matchCollection[i].ToString(); + text = text.Replace(text4, GetGoogleNoTranslateTag(list.Count) + " "); + list.Add(text4); + string text5 = matchCollection[num].ToString(); + text = text.Replace(text5, GetGoogleNoTranslateTag(list.Count) + " "); + list.Add(text5); + } + } + query.Text = text; + query.Tags = list.ToArray(); + } + + public static string GetQueryResult(string text, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict) + { + if (!dict.ContainsKey(text)) + { + return null; + } + TranslationQuery translationQuery = dict[text]; + if (translationQuery.Results == null || translationQuery.Results.Length < 0) + { + return null; + } + if (string.IsNullOrEmpty(LanguageCodeTo)) + { + return translationQuery.Results[0]; + } + int num = Array.IndexOf(translationQuery.TargetLanguagesCode, LanguageCodeTo); + if (num < 0) + { + return null; + } + return translationQuery.Results[num]; + } + + public static string RebuildTranslation(string text, Dictionary<string, TranslationQuery> dict, string LanguageCodeTo) + { + if (!text.Contains("[i2s_")) + { + return RebuildTranslation_Plural(text, dict, LanguageCodeTo); + } + Dictionary<string, string> specializations = SpecializationManager.GetSpecializations(text); + Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); + foreach (KeyValuePair<string, string> item in specializations) + { + dictionary[item.Key] = RebuildTranslation_Plural(item.Value, dict, LanguageCodeTo); + } + return SpecializationManager.SetSpecializedText(dictionary); + } + + private static string RebuildTranslation_Plural(string text, Dictionary<string, TranslationQuery> dict, string LanguageCodeTo) + { + bool flag = text.Contains("{[#"); + bool flag2 = text.Contains("[i2p_"); + if (!HasParameters(text) || (!flag && !flag2)) + { + return GetTranslation(text, LanguageCodeTo, dict); + } + StringBuilder stringBuilder = new StringBuilder(); + string text2 = null; + bool forceTag = flag; + for (ePluralType ePluralType2 = ePluralType.Plural; ePluralType2 >= ePluralType.Zero; ePluralType2--) + { + string text3 = ePluralType2.ToString(); + if (!GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, text3)) + { + continue; + } + string text4 = GetPluralText(text, text3); + int pluralTestNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, ePluralType2); + string pluralParameter = GetPluralParameter(text4, forceTag); + if (!string.IsNullOrEmpty(pluralParameter)) + { + text4 = text4.Replace(pluralParameter, pluralTestNumber.ToString()); + } + string text5 = GetTranslation(text4, LanguageCodeTo, dict); + if (!string.IsNullOrEmpty(pluralParameter)) + { + text5 = text5.Replace(pluralTestNumber.ToString(), pluralParameter); + } + if (ePluralType2 == ePluralType.Plural) + { + text2 = text5; + } + else + { + if (text5 == text2) + { + continue; + } + stringBuilder.AppendFormat("[i2p_{0}]", text3); + } + stringBuilder.Append(text5); + } + return stringBuilder.ToString(); + } + + public static string UppercaseFirst(string s) + { + if (string.IsNullOrEmpty(s)) + { + return string.Empty; + } + char[] array = s.ToLower().ToCharArray(); + array[0] = char.ToUpper(array[0]); + return new string(array); + } + + public static string TitleCase(string s) + { + if (string.IsNullOrEmpty(s)) + { + return string.Empty; + } + return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/HindiFixer.cs b/Thronefall_v1.57/Thronefall/I2.Loc/HindiFixer.cs new file mode 100644 index 0000000..41e3740 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/HindiFixer.cs @@ -0,0 +1,83 @@ +using System.Linq; + +namespace I2.Loc; + +public class HindiFixer +{ + internal static string Fix(string text) + { + char[] array = text.ToCharArray(); + bool flag = false; + for (int i = 0; i < array.Length; i++) + { + if (array[i] == '\u093f' && !char.IsWhiteSpace(array[i - 1]) && array[i - 1] != 0) + { + array[i] = array[i - 1]; + array[i - 1] = '\u093f'; + flag = true; + } + if (i != array.Length - 1) + { + if (array[i] == 'इ' && array[i + 1] == '\u093c') + { + array[i] = 'ऌ'; + array[i + 1] = '\0'; + flag = true; + } + if (array[i] == '\u0943' && array[i + 1] == '\u093c') + { + array[i] = '\u0944'; + array[i + 1] = '\0'; + flag = true; + } + if (array[i] == '\u0901' && array[i + 1] == '\u093c') + { + array[i] = 'ॐ'; + array[i + 1] = '\0'; + flag = true; + } + if (array[i] == 'ऋ' && array[i + 1] == '\u093c') + { + array[i] = 'ॠ'; + array[i + 1] = '\0'; + flag = true; + } + if (array[i] == 'ई' && array[i + 1] == '\u093c') + { + array[i] = 'ॡ'; + array[i + 1] = '\0'; + flag = true; + } + if (array[i] == '\u093f' && array[i + 1] == '\u093c') + { + array[i] = '\u0962'; + array[i + 1] = '\0'; + flag = true; + } + if (array[i] == '\u0940' && array[i + 1] == '\u093c') + { + array[i] = '\u0963'; + array[i + 1] = '\0'; + flag = true; + } + if (array[i] == '।' && array[i + 1] == '\u093c') + { + array[i] = 'ऽ'; + array[i + 1] = '\0'; + flag = true; + } + } + } + if (!flag) + { + return text; + } + string text2 = new string(array.Where((char x) => x != '\0').ToArray()); + if (text2 == text) + { + return text2; + } + text = text2; + return text; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/I2BasePersistentStorage.cs b/Thronefall_v1.57/Thronefall/I2.Loc/I2BasePersistentStorage.cs new file mode 100644 index 0000000..bd4a52c --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/I2BasePersistentStorage.cs @@ -0,0 +1,197 @@ +using System; +using System.Globalization; +using System.IO; +using System.Text; +using UnityEngine; + +namespace I2.Loc; + +public abstract class I2BasePersistentStorage +{ + public virtual void SetSetting_String(string key, string value) + { + try + { + int length = value.Length; + int num = 8000; + if (length <= num) + { + PlayerPrefs.SetString(key, value); + return; + } + int num2 = Mathf.CeilToInt((float)length / (float)num); + for (int i = 0; i < num2; i++) + { + int num3 = num * i; + PlayerPrefs.SetString($"[I2split]{i}{key}", value.Substring(num3, Mathf.Min(num, length - num3))); + } + PlayerPrefs.SetString(key, "[$I2#@div$]" + num2); + } + catch (Exception) + { + Debug.LogError("Error saving PlayerPrefs " + key); + } + } + + public virtual string GetSetting_String(string key, string defaultValue) + { + try + { + string text = PlayerPrefs.GetString(key, defaultValue); + if (!string.IsNullOrEmpty(text) && text.StartsWith("[I2split]", StringComparison.Ordinal)) + { + int num = int.Parse(text.Substring("[I2split]".Length), CultureInfo.InvariantCulture); + text = ""; + for (int i = 0; i < num; i++) + { + text += PlayerPrefs.GetString($"[I2split]{i}{key}", ""); + } + } + return text; + } + catch (Exception) + { + Debug.LogError("Error loading PlayerPrefs " + key); + return defaultValue; + } + } + + public virtual void DeleteSetting(string key) + { + try + { + string @string = PlayerPrefs.GetString(key, null); + if (!string.IsNullOrEmpty(@string) && @string.StartsWith("[I2split]", StringComparison.Ordinal)) + { + int num = int.Parse(@string.Substring("[I2split]".Length), CultureInfo.InvariantCulture); + for (int i = 0; i < num; i++) + { + PlayerPrefs.DeleteKey($"[I2split]{i}{key}"); + } + } + PlayerPrefs.DeleteKey(key); + } + catch (Exception) + { + Debug.LogError("Error deleting PlayerPrefs " + key); + } + } + + public virtual void ForceSaveSettings() + { + PlayerPrefs.Save(); + } + + public virtual bool HasSetting(string key) + { + return PlayerPrefs.HasKey(key); + } + + public virtual bool CanAccessFiles() + { + return true; + } + + private string UpdateFilename(PersistentStorage.eFileType fileType, string fileName) + { + switch (fileType) + { + case PersistentStorage.eFileType.Persistent: + fileName = Application.persistentDataPath + "/" + fileName; + break; + case PersistentStorage.eFileType.Temporal: + fileName = Application.temporaryCachePath + "/" + fileName; + break; + case PersistentStorage.eFileType.Streaming: + fileName = Application.streamingAssetsPath + "/" + fileName; + break; + } + return fileName; + } + + public virtual bool SaveFile(PersistentStorage.eFileType fileType, string fileName, string data, bool logExceptions = true) + { + if (!CanAccessFiles()) + { + return false; + } + try + { + fileName = UpdateFilename(fileType, fileName); + File.WriteAllText(fileName, data, Encoding.UTF8); + return true; + } + catch (Exception ex) + { + if (logExceptions) + { + Debug.LogError("Error saving file '" + fileName + "'\n" + ex); + } + return false; + } + } + + public virtual string LoadFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true) + { + if (!CanAccessFiles()) + { + return null; + } + try + { + fileName = UpdateFilename(fileType, fileName); + return File.ReadAllText(fileName, Encoding.UTF8); + } + catch (Exception ex) + { + if (logExceptions) + { + Debug.LogError("Error loading file '" + fileName + "'\n" + ex); + } + return null; + } + } + + public virtual bool DeleteFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true) + { + if (!CanAccessFiles()) + { + return false; + } + try + { + fileName = UpdateFilename(fileType, fileName); + File.Delete(fileName); + return true; + } + catch (Exception ex) + { + if (logExceptions) + { + Debug.LogError("Error deleting file '" + fileName + "'\n" + ex); + } + return false; + } + } + + public virtual bool HasFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true) + { + if (!CanAccessFiles()) + { + return false; + } + try + { + fileName = UpdateFilename(fileType, fileName); + return File.Exists(fileName); + } + catch (Exception ex) + { + if (logExceptions) + { + Debug.LogError("Error requesting file '" + fileName + "'\n" + ex); + } + return false; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/I2CustomPersistentStorage.cs b/Thronefall_v1.57/Thronefall/I2.Loc/I2CustomPersistentStorage.cs new file mode 100644 index 0000000..f518316 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/I2CustomPersistentStorage.cs @@ -0,0 +1,5 @@ +namespace I2.Loc; + +public class I2CustomPersistentStorage : I2BasePersistentStorage +{ +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/I2Utils.cs b/Thronefall_v1.57/Thronefall/I2.Loc/I2Utils.cs new file mode 100644 index 0000000..a60bb8e --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/I2Utils.cs @@ -0,0 +1,301 @@ +using System; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.Networking; +using UnityEngine.SceneManagement; + +namespace I2.Loc; + +public static class I2Utils +{ + public const string ValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; + + public const string NumberChars = "0123456789"; + + public const string ValidNameSymbols = ".-_$#@*()[]{}+:?!&',^=<>~`"; + + public static string ReverseText(string source) + { + int length = source.Length; + char[] output = new char[length]; + char[] anyOf = new char[2] { '\r', '\n' }; + int i = 0; + while (i < length) + { + int num = source.IndexOfAny(anyOf, i); + if (num < 0) + { + num = length; + } + Reverse(i, num - 1); + for (i = num; i < length && (source[i] == '\r' || source[i] == '\n'); i++) + { + output[i] = source[i]; + } + } + return new string(output); + void Reverse(int start, int end) + { + for (int j = 0; j <= end - start; j++) + { + output[end - j] = source[start + j]; + } + } + } + + public static string RemoveNonASCII(string text, bool allowCategory = false) + { + if (string.IsNullOrEmpty(text)) + { + return text; + } + int num = 0; + char[] array = new char[text.Length]; + bool flag = false; + string text2 = text.Trim(); + foreach (char c in text2) + { + char c2 = ' '; + if ((allowCategory && (c == '\\' || c == '"' || c == '/')) || char.IsLetterOrDigit(c) || ".-_$#@*()[]{}+:?!&',^=<>~`".IndexOf(c) >= 0) + { + c2 = c; + } + if (char.IsWhiteSpace(c2)) + { + if (!flag) + { + if (num > 0) + { + array[num++] = ' '; + } + flag = true; + } + } + else + { + flag = false; + array[num++] = c2; + } + } + return new string(array, 0, num); + } + + public static string GetValidTermName(string text, bool allowCategory = false) + { + if (text == null) + { + return null; + } + text = RemoveTags(text); + return RemoveNonASCII(text, allowCategory); + } + + public static string SplitLine(string line, int maxCharacters) + { + if (maxCharacters <= 0 || line.Length < maxCharacters) + { + return line; + } + char[] array = line.ToCharArray(); + bool flag = true; + bool flag2 = false; + int i = 0; + int num = 0; + for (; i < array.Length; i++) + { + if (flag) + { + num++; + if (array[i] == '\n') + { + num = 0; + } + if (num >= maxCharacters && char.IsWhiteSpace(array[i])) + { + array[i] = '\n'; + flag = false; + flag2 = false; + } + } + else if (!char.IsWhiteSpace(array[i])) + { + flag = true; + num = 0; + } + else if (array[i] != '\n') + { + array[i] = '\0'; + } + else + { + if (!flag2) + { + array[i] = '\0'; + } + flag2 = true; + } + } + return new string(array.Where((char c) => c != '\0').ToArray()); + } + + public static bool FindNextTag(string line, int iStart, out int tagStart, out int tagEnd) + { + tagStart = -1; + tagEnd = -1; + int length = line.Length; + tagStart = iStart; + while (tagStart < length && line[tagStart] != '[' && line[tagStart] != '(' && line[tagStart] != '{' && line[tagStart] != '<') + { + tagStart++; + } + if (tagStart == length) + { + return false; + } + bool flag = false; + for (tagEnd = tagStart + 1; tagEnd < length; tagEnd++) + { + char c = line[tagEnd]; + if (c == ']' || c == ')' || c == '}' || c == '>') + { + if (flag) + { + return FindNextTag(line, tagEnd + 1, out tagStart, out tagEnd); + } + return true; + } + if (c > 'ÿ') + { + flag = true; + } + } + return false; + } + + public static string RemoveTags(string text) + { + return Regex.Replace(text, "\\{\\[(.*?)]}|\\[(.*?)]|\\<(.*?)>", ""); + } + + public static bool RemoveResourcesPath(ref string sPath) + { + int num = sPath.IndexOf("\\Resources\\", StringComparison.Ordinal); + int num2 = sPath.IndexOf("\\Resources/", StringComparison.Ordinal); + int num3 = sPath.IndexOf("/Resources\\", StringComparison.Ordinal); + int num4 = sPath.IndexOf("/Resources/", StringComparison.Ordinal); + int num5 = Mathf.Max(num, num2, num3, num4); + bool result = false; + if (num5 >= 0) + { + sPath = sPath.Substring(num5 + 11); + result = true; + } + else + { + num5 = sPath.LastIndexOfAny(LanguageSourceData.CategorySeparators); + if (num5 > 0) + { + sPath = sPath.Substring(num5 + 1); + } + } + string extension = Path.GetExtension(sPath); + if (!string.IsNullOrEmpty(extension)) + { + sPath = sPath.Substring(0, sPath.Length - extension.Length); + } + return result; + } + + public static bool IsPlaying() + { + if (Application.isPlaying) + { + return true; + } + return false; + } + + public static string GetPath(this Transform tr) + { + Transform parent = tr.parent; + if (tr == null) + { + return tr.name; + } + return parent.GetPath() + "/" + tr.name; + } + + public static Transform FindObject(string objectPath) + { + return FindObject(SceneManager.GetActiveScene(), objectPath); + } + + public static Transform FindObject(Scene scene, string objectPath) + { + GameObject[] rootGameObjects = scene.GetRootGameObjects(); + for (int i = 0; i < rootGameObjects.Length; i++) + { + Transform transform = rootGameObjects[i].transform; + if (transform.name == objectPath) + { + return transform; + } + if (objectPath.StartsWith(transform.name + "/", StringComparison.Ordinal)) + { + return FindObject(transform, objectPath.Substring(transform.name.Length + 1)); + } + } + return null; + } + + public static Transform FindObject(Transform root, string objectPath) + { + for (int i = 0; i < root.childCount; i++) + { + Transform child = root.GetChild(i); + if (child.name == objectPath) + { + return child; + } + if (objectPath.StartsWith(child.name + "/", StringComparison.Ordinal)) + { + return FindObject(child, objectPath.Substring(child.name.Length + 1)); + } + } + return null; + } + + public static H FindInParents<H>(Transform tr) where H : Component + { + if (!tr) + { + return null; + } + H component = tr.GetComponent<H>(); + while (!(UnityEngine.Object)component && (bool)tr) + { + component = tr.GetComponent<H>(); + tr = tr.parent; + } + return component; + } + + public static string GetCaptureMatch(Match match) + { + for (int num = match.Groups.Count - 1; num >= 0; num--) + { + if (match.Groups[num].Success) + { + return match.Groups[num].ToString(); + } + } + return match.ToString(); + } + + public static void SendWebRequest(UnityWebRequest www) + { + www.SendWebRequest(); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ILanguageSource.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ILanguageSource.cs new file mode 100644 index 0000000..7717e4d --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ILanguageSource.cs @@ -0,0 +1,6 @@ +namespace I2.Loc; + +public interface ILanguageSource +{ + LanguageSourceData SourceData { get; set; } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizationParamsManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizationParamsManager.cs new file mode 100644 index 0000000..c96bd20 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizationParamsManager.cs @@ -0,0 +1,6 @@ +namespace I2.Loc; + +public interface ILocalizationParamsManager +{ + string GetParameterValue(string Param); +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizeTarget.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizeTarget.cs new file mode 100644 index 0000000..2d8c155 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizeTarget.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +namespace I2.Loc; + +public abstract class ILocalizeTarget : ScriptableObject +{ + public abstract bool IsValid(Localize cmp); + + public abstract void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm); + + public abstract void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation); + + public abstract bool CanUseSecondaryTerm(); + + public abstract bool AllowMainTermToBeRTL(); + + public abstract bool AllowSecondTermToBeRTL(); + + public abstract eTermType GetPrimaryTermType(Localize cmp); + + public abstract eTermType GetSecondaryTermType(Localize cmp); +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizeTargetDescriptor.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizeTargetDescriptor.cs new file mode 100644 index 0000000..0b807cd --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ILocalizeTargetDescriptor.cs @@ -0,0 +1,16 @@ +using System; + +namespace I2.Loc; + +public abstract class ILocalizeTargetDescriptor +{ + public string Name; + + public int Priority; + + public abstract bool CanLocalize(Localize cmp); + + public abstract ILocalizeTarget CreateTarget(Localize cmp); + + public abstract Type GetTargetType(); +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/IResourceManager_Bundles.cs b/Thronefall_v1.57/Thronefall/I2.Loc/IResourceManager_Bundles.cs new file mode 100644 index 0000000..1ba81a2 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/IResourceManager_Bundles.cs @@ -0,0 +1,9 @@ +using System; +using UnityEngine; + +namespace I2.Loc; + +public interface IResourceManager_Bundles +{ + UnityEngine.Object LoadFromBundle(string path, Type assetType); +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/IsolatedArabicLetters.cs b/Thronefall_v1.57/Thronefall/I2.Loc/IsolatedArabicLetters.cs new file mode 100644 index 0000000..93a8938 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/IsolatedArabicLetters.cs @@ -0,0 +1,46 @@ +namespace I2.Loc; + +internal enum IsolatedArabicLetters +{ + Hamza = 65152, + Alef = 65165, + AlefHamza = 65155, + WawHamza = 65157, + AlefMaksoor = 65159, + AlefMaksora = 64508, + HamzaNabera = 65161, + Ba = 65167, + Ta = 65173, + Tha2 = 65177, + Jeem = 65181, + H7aa = 65185, + Khaa2 = 65189, + Dal = 65193, + Thal = 65195, + Ra2 = 65197, + Zeen = 65199, + Seen = 65201, + Sheen = 65205, + S9a = 65209, + Dha = 65213, + T6a = 65217, + T6ha = 65221, + Ain = 65225, + Gain = 65229, + Fa = 65233, + Gaf = 65237, + Kaf = 65241, + Lam = 65245, + Meem = 65249, + Noon = 65253, + Ha = 65257, + Waw = 65261, + Ya = 65265, + AlefMad = 65153, + TaMarboota = 65171, + PersianPe = 64342, + PersianChe = 64378, + PersianZe = 64394, + PersianGaf = 64402, + PersianGaf2 = 64398 +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LanguageData.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageData.cs new file mode 100644 index 0000000..566d28a --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageData.cs @@ -0,0 +1,67 @@ +using System; + +namespace I2.Loc; + +[Serializable] +public class LanguageData +{ + public string Name; + + public string Code; + + public byte Flags; + + [NonSerialized] + public bool Compressed; + + public bool IsEnabled() + { + return (Flags & 1) == 0; + } + + public void SetEnabled(bool bEnabled) + { + if (bEnabled) + { + Flags = (byte)(Flags & 0xFFFFFFFEu); + } + else + { + Flags |= 1; + } + } + + public bool IsLoaded() + { + return (Flags & 4) == 0; + } + + public bool CanBeUnloaded() + { + return (Flags & 2) == 0; + } + + public void SetLoaded(bool loaded) + { + if (loaded) + { + Flags = (byte)(Flags & 0xFFFFFFFBu); + } + else + { + Flags |= 4; + } + } + + public void SetCanBeUnLoaded(bool allowUnloading) + { + if (allowUnloading) + { + Flags = (byte)(Flags & 0xFFFFFFFDu); + } + else + { + Flags |= 2; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSource.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSource.cs new file mode 100644 index 0000000..15023e7 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSource.cs @@ -0,0 +1,145 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace I2.Loc; + +[AddComponentMenu("I2/Localization/Source")] +[ExecuteInEditMode] +public class LanguageSource : MonoBehaviour, ISerializationCallbackReceiver, ILanguageSource +{ + public delegate void fnOnSourceUpdated(LanguageSourceData source, bool ReceivedNewData, string errorMsg); + + public LanguageSourceData mSource = new LanguageSourceData(); + + public int version; + + public bool NeverDestroy; + + public bool UserAgreesToHaveItOnTheScene; + + public bool UserAgreesToHaveItInsideThePluginsFolder; + + public bool GoogleLiveSyncIsUptoDate = true; + + public List<Object> Assets = new List<Object>(); + + public string Google_WebServiceURL; + + public string Google_SpreadsheetKey; + + public string Google_SpreadsheetName; + + public string Google_LastUpdatedVersion; + + public LanguageSourceData.eGoogleUpdateFrequency GoogleUpdateFrequency = LanguageSourceData.eGoogleUpdateFrequency.Weekly; + + public float GoogleUpdateDelay = 5f; + + public List<LanguageData> mLanguages = new List<LanguageData>(); + + public bool IgnoreDeviceLanguage; + + public LanguageSourceData.eAllowUnloadLanguages _AllowUnloadingLanguages; + + public List<TermData> mTerms = new List<TermData>(); + + public bool CaseInsensitiveTerms; + + public LanguageSourceData.MissingTranslationAction OnMissingTranslation = LanguageSourceData.MissingTranslationAction.Fallback; + + public string mTerm_AppName; + + public LanguageSourceData SourceData + { + get + { + return mSource; + } + set + { + mSource = value; + } + } + + public event fnOnSourceUpdated Event_OnSourceUpdateFromGoogle; + + private void Awake() + { + mSource.owner = this; + mSource.Awake(); + } + + private void OnDestroy() + { + NeverDestroy = false; + if (!NeverDestroy) + { + mSource.OnDestroy(); + } + } + + public string GetSourceName() + { + string text = base.gameObject.name; + Transform parent = base.transform.parent; + while ((bool)parent) + { + text = parent.name + "_" + text; + parent = parent.parent; + } + return text; + } + + public void OnBeforeSerialize() + { + version = 1; + } + + public void OnAfterDeserialize() + { + if (version != 0 && mSource != null) + { + return; + } + mSource = new LanguageSourceData(); + mSource.owner = this; + mSource.UserAgreesToHaveItOnTheScene = UserAgreesToHaveItOnTheScene; + mSource.UserAgreesToHaveItInsideThePluginsFolder = UserAgreesToHaveItInsideThePluginsFolder; + mSource.IgnoreDeviceLanguage = IgnoreDeviceLanguage; + mSource._AllowUnloadingLanguages = _AllowUnloadingLanguages; + mSource.CaseInsensitiveTerms = CaseInsensitiveTerms; + mSource.OnMissingTranslation = OnMissingTranslation; + mSource.mTerm_AppName = mTerm_AppName; + mSource.GoogleLiveSyncIsUptoDate = GoogleLiveSyncIsUptoDate; + mSource.Google_WebServiceURL = Google_WebServiceURL; + mSource.Google_SpreadsheetKey = Google_SpreadsheetKey; + mSource.Google_SpreadsheetName = Google_SpreadsheetName; + mSource.Google_LastUpdatedVersion = Google_LastUpdatedVersion; + mSource.GoogleUpdateFrequency = GoogleUpdateFrequency; + mSource.GoogleUpdateDelay = GoogleUpdateDelay; + mSource.Event_OnSourceUpdateFromGoogle += this.Event_OnSourceUpdateFromGoogle; + if (mLanguages != null && mLanguages.Count > 0) + { + mSource.mLanguages.Clear(); + mSource.mLanguages.AddRange(mLanguages); + mLanguages.Clear(); + } + if (Assets != null && Assets.Count > 0) + { + mSource.Assets.Clear(); + mSource.Assets.AddRange(Assets); + Assets.Clear(); + } + if (mTerms != null && mTerms.Count > 0) + { + mSource.mTerms.Clear(); + for (int i = 0; i < mTerms.Count; i++) + { + mSource.mTerms.Add(mTerms[i]); + } + mTerms.Clear(); + } + version = 1; + this.Event_OnSourceUpdateFromGoogle = null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSourceAsset.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSourceAsset.cs new file mode 100644 index 0000000..5c4e9b6 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSourceAsset.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +namespace I2.Loc; + +[CreateAssetMenu(fileName = "I2Languages", menuName = "I2 Localization/LanguageSource", order = 1)] +public class LanguageSourceAsset : ScriptableObject, ILanguageSource +{ + public LanguageSourceData mSource = new LanguageSourceData(); + + public LanguageSourceData SourceData + { + get + { + return mSource; + } + set + { + mSource = value; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSourceData.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSourceData.cs new file mode 100644 index 0000000..47646f7 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LanguageSourceData.cs @@ -0,0 +1,1661 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.Networking; +using UnityEngine.SceneManagement; + +namespace I2.Loc; + +[Serializable] +[ExecuteInEditMode] +public class LanguageSourceData +{ + public enum MissingTranslationAction + { + Empty, + Fallback, + ShowWarning, + ShowTerm + } + + public enum eAllowUnloadLanguages + { + Never, + OnlyInDevice, + EditorAndDevice + } + + public enum eGoogleUpdateFrequency + { + Always, + Never, + Daily, + Weekly, + Monthly, + OnlyOnce, + EveryOtherDay + } + + public enum eGoogleUpdateSynchronization + { + Manual, + OnSceneLoaded, + AsSoonAsDownloaded + } + + [NonSerialized] + public ILanguageSource owner; + + public bool UserAgreesToHaveItOnTheScene; + + public bool UserAgreesToHaveItInsideThePluginsFolder; + + public bool GoogleLiveSyncIsUptoDate = true; + + [NonSerialized] + public bool mIsGlobalSource; + + public List<TermData> mTerms = new List<TermData>(); + + public bool CaseInsensitiveTerms; + + [NonSerialized] + public Dictionary<string, TermData> mDictionary = new Dictionary<string, TermData>(StringComparer.Ordinal); + + public MissingTranslationAction OnMissingTranslation = MissingTranslationAction.Fallback; + + public string mTerm_AppName; + + public List<LanguageData> mLanguages = new List<LanguageData>(); + + public bool IgnoreDeviceLanguage; + + public eAllowUnloadLanguages _AllowUnloadingLanguages; + + public string Google_WebServiceURL; + + public string Google_SpreadsheetKey; + + public string Google_SpreadsheetName; + + public string Google_LastUpdatedVersion; + + public eGoogleUpdateFrequency GoogleUpdateFrequency = eGoogleUpdateFrequency.Weekly; + + public eGoogleUpdateFrequency GoogleInEditorCheckFrequency = eGoogleUpdateFrequency.Daily; + + public eGoogleUpdateSynchronization GoogleUpdateSynchronization = eGoogleUpdateSynchronization.OnSceneLoaded; + + public float GoogleUpdateDelay; + + public List<UnityEngine.Object> Assets = new List<UnityEngine.Object>(); + + [NonSerialized] + public Dictionary<string, UnityEngine.Object> mAssetDictionary = new Dictionary<string, UnityEngine.Object>(StringComparer.Ordinal); + + private string mDelayedGoogleData; + + public static string EmptyCategory = "Default"; + + public static char[] CategorySeparators = "/\\".ToCharArray(); + + public UnityEngine.Object ownerObject => owner as UnityEngine.Object; + + public event LanguageSource.fnOnSourceUpdated Event_OnSourceUpdateFromGoogle; + + public void Awake() + { + LocalizationManager.AddSource(this); + UpdateDictionary(); + UpdateAssetDictionary(); + LocalizationManager.LocalizeAll(Force: true); + } + + public void OnDestroy() + { + LocalizationManager.RemoveSource(this); + } + + public bool IsEqualTo(LanguageSourceData Source) + { + if (Source.mLanguages.Count != mLanguages.Count) + { + return false; + } + int i = 0; + for (int count = mLanguages.Count; i < count; i++) + { + if (Source.GetLanguageIndex(mLanguages[i].Name) < 0) + { + return false; + } + } + if (Source.mTerms.Count != mTerms.Count) + { + return false; + } + for (int j = 0; j < mTerms.Count; j++) + { + if (Source.GetTermData(mTerms[j].Term) == null) + { + return false; + } + } + return true; + } + + internal bool ManagerHasASimilarSource() + { + int i = 0; + for (int count = LocalizationManager.Sources.Count; i < count; i++) + { + LanguageSourceData languageSourceData = LocalizationManager.Sources[i]; + if (languageSourceData != null && languageSourceData.IsEqualTo(this) && languageSourceData != this) + { + return true; + } + } + return false; + } + + public void ClearAllData() + { + mTerms.Clear(); + mLanguages.Clear(); + mDictionary.Clear(); + mAssetDictionary.Clear(); + } + + public bool IsGlobalSource() + { + return mIsGlobalSource; + } + + public void Editor_SetDirty() + { + } + + public void UpdateAssetDictionary() + { + Assets.RemoveAll((UnityEngine.Object x) => x == null); + mAssetDictionary = Assets.Distinct().GroupBy((UnityEngine.Object o) => o.name, StringComparer.Ordinal).ToDictionary((IGrouping<string, UnityEngine.Object> g) => g.Key, (IGrouping<string, UnityEngine.Object> g) => g.First(), StringComparer.Ordinal); + } + + public UnityEngine.Object FindAsset(string Name) + { + if (Assets != null) + { + if (mAssetDictionary == null || mAssetDictionary.Count != Assets.Count) + { + UpdateAssetDictionary(); + } + if (mAssetDictionary.TryGetValue(Name, out var value)) + { + return value; + } + } + return null; + } + + public bool HasAsset(UnityEngine.Object Obj) + { + return Assets.Contains(Obj); + } + + public void AddAsset(UnityEngine.Object Obj) + { + if (!Assets.Contains(Obj)) + { + Assets.Add(Obj); + UpdateAssetDictionary(); + } + } + + private string Export_Language_to_Cache(int langIndex, bool fillTermWithFallback) + { + if (!mLanguages[langIndex].IsLoaded()) + { + return null; + } + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < mTerms.Count; i++) + { + if (i > 0) + { + stringBuilder.Append("[i2t]"); + } + TermData termData = mTerms[i]; + stringBuilder.Append(termData.Term); + stringBuilder.Append("="); + string Translation = termData.Languages[langIndex]; + if (OnMissingTranslation == MissingTranslationAction.Fallback && string.IsNullOrEmpty(Translation) && TryGetFallbackTranslation(termData, out Translation, langIndex, null, skipDisabled: true)) + { + stringBuilder.Append("[i2fb]"); + if (fillTermWithFallback) + { + termData.Languages[langIndex] = Translation; + } + } + if (!string.IsNullOrEmpty(Translation)) + { + stringBuilder.Append(Translation); + } + } + return stringBuilder.ToString(); + } + + public string Export_I2CSV(string Category, char Separator = ',', bool specializationsAsRows = true) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append("Key[*]Type[*]Desc"); + foreach (LanguageData mLanguage in mLanguages) + { + stringBuilder.Append("[*]"); + if (!mLanguage.IsEnabled()) + { + stringBuilder.Append('$'); + } + stringBuilder.Append(GoogleLanguages.GetCodedLanguage(mLanguage.Name, mLanguage.Code)); + } + stringBuilder.Append("[ln]"); + mTerms.Sort((TermData a, TermData b) => string.CompareOrdinal(a.Term, b.Term)); + int count = mLanguages.Count; + bool flag = true; + foreach (TermData mTerm in mTerms) + { + string term; + if (string.IsNullOrEmpty(Category) || (Category == EmptyCategory && mTerm.Term.IndexOfAny(CategorySeparators) < 0)) + { + term = mTerm.Term; + } + else + { + if (!mTerm.Term.StartsWith(Category + "/", StringComparison.Ordinal) || !(Category != mTerm.Term)) + { + continue; + } + term = mTerm.Term.Substring(Category.Length + 1); + } + if (!flag) + { + stringBuilder.Append("[ln]"); + } + flag = false; + if (!specializationsAsRows) + { + AppendI2Term(stringBuilder, count, term, mTerm, Separator, null); + continue; + } + List<string> allSpecializations = mTerm.GetAllSpecializations(); + for (int i = 0; i < allSpecializations.Count; i++) + { + if (i != 0) + { + stringBuilder.Append("[ln]"); + } + string forceSpecialization = allSpecializations[i]; + AppendI2Term(stringBuilder, count, term, mTerm, Separator, forceSpecialization); + } + } + return stringBuilder.ToString(); + } + + private static void AppendI2Term(StringBuilder Builder, int nLanguages, string Term, TermData termData, char Separator, string forceSpecialization) + { + AppendI2Text(Builder, Term); + if (!string.IsNullOrEmpty(forceSpecialization) && forceSpecialization != "Any") + { + Builder.Append("["); + Builder.Append(forceSpecialization); + Builder.Append("]"); + } + Builder.Append("[*]"); + Builder.Append(termData.TermType.ToString()); + Builder.Append("[*]"); + Builder.Append(termData.Description); + for (int i = 0; i < Mathf.Min(nLanguages, termData.Languages.Length); i++) + { + Builder.Append("[*]"); + string text = termData.Languages[i]; + if (!string.IsNullOrEmpty(forceSpecialization)) + { + text = termData.GetTranslation(i, forceSpecialization); + } + AppendI2Text(Builder, text); + } + } + + private static void AppendI2Text(StringBuilder Builder, string text) + { + if (!string.IsNullOrEmpty(text)) + { + if (text.StartsWith("'", StringComparison.Ordinal) || text.StartsWith("=", StringComparison.Ordinal)) + { + Builder.Append('\''); + } + Builder.Append(text); + } + } + + public string Export_CSV(string Category, char Separator = ',', bool specializationsAsRows = true) + { + StringBuilder stringBuilder = new StringBuilder(); + int count = mLanguages.Count; + stringBuilder.AppendFormat("Key{0}Type{0}Desc", Separator); + foreach (LanguageData mLanguage in mLanguages) + { + stringBuilder.Append(Separator); + if (!mLanguage.IsEnabled()) + { + stringBuilder.Append('$'); + } + AppendString(stringBuilder, GoogleLanguages.GetCodedLanguage(mLanguage.Name, mLanguage.Code), Separator); + } + stringBuilder.Append("\n"); + mTerms.Sort((TermData a, TermData b) => string.CompareOrdinal(a.Term, b.Term)); + foreach (TermData mTerm in mTerms) + { + string term; + if (string.IsNullOrEmpty(Category) || (Category == EmptyCategory && mTerm.Term.IndexOfAny(CategorySeparators) < 0)) + { + term = mTerm.Term; + } + else + { + if (!mTerm.Term.StartsWith(Category + "/", StringComparison.Ordinal) || !(Category != mTerm.Term)) + { + continue; + } + term = mTerm.Term.Substring(Category.Length + 1); + } + if (specializationsAsRows) + { + foreach (string allSpecialization in mTerm.GetAllSpecializations()) + { + AppendTerm(stringBuilder, count, term, mTerm, allSpecialization, Separator); + } + } + else + { + AppendTerm(stringBuilder, count, term, mTerm, null, Separator); + } + } + return stringBuilder.ToString(); + } + + private static void AppendTerm(StringBuilder Builder, int nLanguages, string Term, TermData termData, string specialization, char Separator) + { + AppendString(Builder, Term, Separator); + if (!string.IsNullOrEmpty(specialization) && specialization != "Any") + { + Builder.AppendFormat("[{0}]", specialization); + } + Builder.Append(Separator); + Builder.Append(termData.TermType.ToString()); + Builder.Append(Separator); + AppendString(Builder, termData.Description, Separator); + for (int i = 0; i < Mathf.Min(nLanguages, termData.Languages.Length); i++) + { + Builder.Append(Separator); + string text = termData.Languages[i]; + if (!string.IsNullOrEmpty(specialization)) + { + text = termData.GetTranslation(i, specialization); + } + AppendTranslation(Builder, text, Separator, null); + } + Builder.Append("\n"); + } + + private static void AppendString(StringBuilder Builder, string Text, char Separator) + { + if (!string.IsNullOrEmpty(Text)) + { + Text = Text.Replace("\\n", "\n"); + if (Text.IndexOfAny((Separator + "\n\"").ToCharArray()) >= 0) + { + Text = Text.Replace("\"", "\"\""); + Builder.AppendFormat("\"{0}\"", Text); + } + else + { + Builder.Append(Text); + } + } + } + + private static void AppendTranslation(StringBuilder Builder, string Text, char Separator, string tags) + { + if (!string.IsNullOrEmpty(Text)) + { + Text = Text.Replace("\\n", "\n"); + if (Text.IndexOfAny((Separator + "\n\"").ToCharArray()) >= 0) + { + Text = Text.Replace("\"", "\"\""); + Builder.AppendFormat("\"{0}{1}\"", tags, Text); + } + else + { + Builder.Append(tags); + Builder.Append(Text); + } + } + } + + public UnityWebRequest Export_Google_CreateWWWcall(eSpreadsheetUpdateMode UpdateMode = eSpreadsheetUpdateMode.Replace) + { + string value = Export_Google_CreateData(); + WWWForm wWWForm = new WWWForm(); + wWWForm.AddField("key", Google_SpreadsheetKey); + wWWForm.AddField("action", "SetLanguageSource"); + wWWForm.AddField("data", value); + wWWForm.AddField("updateMode", UpdateMode.ToString()); + UnityWebRequest unityWebRequest = UnityWebRequest.Post(LocalizationManager.GetWebServiceURL(this), wWWForm); + I2Utils.SendWebRequest(unityWebRequest); + return unityWebRequest; + } + + private string Export_Google_CreateData() + { + List<string> categories = GetCategories(OnlyMainCategory: true); + StringBuilder stringBuilder = new StringBuilder(); + bool flag = true; + foreach (string item in categories) + { + if (flag) + { + flag = false; + } + else + { + stringBuilder.Append("<I2Loc>"); + } + bool specializationsAsRows = true; + string value = Export_I2CSV(item, ',', specializationsAsRows); + stringBuilder.Append(item); + stringBuilder.Append("<I2Loc>"); + stringBuilder.Append(value); + } + return stringBuilder.ToString(); + } + + public string Import_CSV(string Category, string CSVstring, eSpreadsheetUpdateMode UpdateMode = eSpreadsheetUpdateMode.Replace, char Separator = ',') + { + List<string[]> cSV = LocalizationReader.ReadCSV(CSVstring, Separator); + return Import_CSV(Category, cSV, UpdateMode); + } + + public string Import_I2CSV(string Category, string I2CSVstring, eSpreadsheetUpdateMode UpdateMode = eSpreadsheetUpdateMode.Replace) + { + List<string[]> cSV = LocalizationReader.ReadI2CSV(I2CSVstring); + return Import_CSV(Category, cSV, UpdateMode); + } + + public string Import_CSV(string Category, List<string[]> CSV, eSpreadsheetUpdateMode UpdateMode = eSpreadsheetUpdateMode.Replace) + { + string[] array = CSV[0]; + int num = 1; + int num2 = -1; + int num3 = -1; + string[] texts = new string[1] { "Key" }; + string[] texts2 = new string[1] { "Type" }; + string[] texts3 = new string[2] { "Desc", "Description" }; + if (array.Length > 1 && ArrayContains(array[0], texts)) + { + if (UpdateMode == eSpreadsheetUpdateMode.Replace) + { + ClearAllData(); + } + if (array.Length > 2) + { + if (ArrayContains(array[1], texts2)) + { + num2 = 1; + num = 2; + } + if (ArrayContains(array[1], texts3)) + { + num3 = 1; + num = 2; + } + } + if (array.Length > 3) + { + if (ArrayContains(array[2], texts2)) + { + num2 = 2; + num = 3; + } + if (ArrayContains(array[2], texts3)) + { + num3 = 2; + num = 3; + } + } + int num4 = Mathf.Max(array.Length - num, 0); + int[] array2 = new int[num4]; + for (int i = 0; i < num4; i++) + { + if (string.IsNullOrEmpty(array[i + num])) + { + array2[i] = -1; + continue; + } + string text = array[i + num]; + bool flag = true; + if (text.StartsWith("$", StringComparison.Ordinal)) + { + flag = false; + text = text.Substring(1); + } + GoogleLanguages.UnPackCodeFromLanguageName(text, out var Language, out var code); + int num5 = -1; + num5 = (string.IsNullOrEmpty(code) ? GetLanguageIndex(Language, AllowDiscartingRegion: true, SkipDisabled: false) : GetLanguageIndexFromCode(code)); + if (num5 < 0) + { + LanguageData languageData = new LanguageData(); + languageData.Name = Language; + languageData.Code = code; + languageData.Flags = (byte)(0u | ((!flag) ? 1u : 0u)); + mLanguages.Add(languageData); + num5 = mLanguages.Count - 1; + } + array2[i] = num5; + } + num4 = mLanguages.Count; + int j = 0; + for (int count = mTerms.Count; j < count; j++) + { + TermData termData = mTerms[j]; + if (termData.Languages.Length < num4) + { + Array.Resize(ref termData.Languages, num4); + Array.Resize(ref termData.Flags, num4); + } + } + int k = 1; + for (int count2 = CSV.Count; k < count2; k++) + { + array = CSV[k]; + string Term = (string.IsNullOrEmpty(Category) ? array[0] : (Category + "/" + array[0])); + string text2 = null; + if (Term.EndsWith("]", StringComparison.Ordinal)) + { + int num6 = Term.LastIndexOf('['); + if (num6 > 0) + { + text2 = Term.Substring(num6 + 1, Term.Length - num6 - 2); + if (text2 == "touch") + { + text2 = "Touch"; + } + Term = Term.Remove(num6); + } + } + ValidateFullTerm(ref Term); + if (string.IsNullOrEmpty(Term)) + { + continue; + } + TermData termData2 = GetTermData(Term); + if (termData2 == null) + { + termData2 = new TermData(); + termData2.Term = Term; + termData2.Languages = new string[mLanguages.Count]; + termData2.Flags = new byte[mLanguages.Count]; + for (int l = 0; l < mLanguages.Count; l++) + { + termData2.Languages[l] = string.Empty; + } + mTerms.Add(termData2); + mDictionary.Add(Term, termData2); + } + else if (UpdateMode == eSpreadsheetUpdateMode.AddNewTerms) + { + continue; + } + if (num2 > 0) + { + termData2.TermType = GetTermType(array[num2]); + } + if (num3 > 0) + { + termData2.Description = array[num3]; + } + for (int m = 0; m < array2.Length && m < array.Length - num; m++) + { + if (string.IsNullOrEmpty(array[m + num])) + { + continue; + } + int num7 = array2[m]; + if (num7 >= 0) + { + string text3 = array[m + num]; + if (text3 == "-") + { + text3 = string.Empty; + } + else if (text3 == "") + { + text3 = null; + } + termData2.SetTranslation(num7, text3, text2); + } + } + } + if (Application.isPlaying) + { + SaveLanguages(HasUnloadedLanguages()); + } + return string.Empty; + } + return "Bad Spreadsheet Format.\nFirst columns should be 'Key', 'Type' and 'Desc'"; + } + + private bool ArrayContains(string MainText, params string[] texts) + { + int i = 0; + for (int num = texts.Length; i < num; i++) + { + if (MainText.IndexOf(texts[i], StringComparison.OrdinalIgnoreCase) >= 0) + { + return true; + } + } + return false; + } + + public static eTermType GetTermType(string type) + { + int i = 0; + for (int num = 10; i <= num; i++) + { + eTermType eTermType2 = (eTermType)i; + if (string.Equals(eTermType2.ToString(), type, StringComparison.OrdinalIgnoreCase)) + { + return (eTermType)i; + } + } + return eTermType.Text; + } + + private void Import_Language_from_Cache(int langIndex, string langData, bool useFallback, bool onlyCurrentSpecialization) + { + int num = 0; + while (num < langData.Length) + { + int num2 = langData.IndexOf("[i2t]", num, StringComparison.Ordinal); + if (num2 < 0) + { + num2 = langData.Length; + } + int num3 = langData.IndexOf("=", num, StringComparison.Ordinal); + if (num3 >= num2) + { + break; + } + string term = langData.Substring(num, num3 - num); + num = num3 + 1; + TermData termData = GetTermData(term); + if (termData != null) + { + string text = null; + if (num != num2) + { + text = langData.Substring(num, num2 - num); + if (text.StartsWith("[i2fb]", StringComparison.Ordinal)) + { + text = (useFallback ? text.Substring(6) : null); + } + if (onlyCurrentSpecialization && text != null) + { + text = SpecializationManager.GetSpecializedText(text); + } + } + termData.Languages[langIndex] = text; + } + num = num2 + 5; + } + } + + public static void FreeUnusedLanguages() + { + LanguageSourceData languageSourceData = LocalizationManager.Sources[0]; + int languageIndex = languageSourceData.GetLanguageIndex(LocalizationManager.CurrentLanguage); + for (int i = 0; i < languageSourceData.mTerms.Count; i++) + { + TermData termData = languageSourceData.mTerms[i]; + for (int j = 0; j < termData.Languages.Length; j++) + { + if (j != languageIndex) + { + termData.Languages[j] = null; + } + } + } + } + + public void Import_Google_FromCache() + { + if (GoogleUpdateFrequency == eGoogleUpdateFrequency.Never || !I2Utils.IsPlaying()) + { + return; + } + string sourcePlayerPrefName = GetSourcePlayerPrefName(); + string text = PersistentStorage.LoadFile(PersistentStorage.eFileType.Persistent, "I2Source_" + sourcePlayerPrefName + ".loc", logExceptions: false); + if (string.IsNullOrEmpty(text)) + { + return; + } + if (text.StartsWith("[i2e]", StringComparison.Ordinal)) + { + text = StringObfucator.Decode(text.Substring(5, text.Length - 5)); + } + bool flag = false; + string text2 = Google_LastUpdatedVersion; + if (PersistentStorage.HasSetting("I2SourceVersion_" + sourcePlayerPrefName)) + { + text2 = PersistentStorage.GetSetting_String("I2SourceVersion_" + sourcePlayerPrefName, Google_LastUpdatedVersion); + flag = IsNewerVersion(Google_LastUpdatedVersion, text2); + } + if (!flag) + { + PersistentStorage.DeleteFile(PersistentStorage.eFileType.Persistent, "I2Source_" + sourcePlayerPrefName + ".loc", logExceptions: false); + PersistentStorage.DeleteSetting("I2SourceVersion_" + sourcePlayerPrefName); + return; + } + if (text2.Length > 19) + { + text2 = string.Empty; + } + Google_LastUpdatedVersion = text2; + Import_Google_Result(text, eSpreadsheetUpdateMode.Replace); + } + + private bool IsNewerVersion(string currentVersion, string newVersion) + { + if (string.IsNullOrEmpty(newVersion)) + { + return false; + } + if (string.IsNullOrEmpty(currentVersion)) + { + return true; + } + if (!long.TryParse(newVersion, out var result) || !long.TryParse(currentVersion, out var result2)) + { + return true; + } + return result > result2; + } + + public void Import_Google(bool ForceUpdate, bool justCheck) + { + if ((!ForceUpdate && GoogleUpdateFrequency == eGoogleUpdateFrequency.Never) || !I2Utils.IsPlaying()) + { + return; + } + eGoogleUpdateFrequency googleUpdateFrequency = GoogleUpdateFrequency; + string sourcePlayerPrefName = GetSourcePlayerPrefName(); + if (!ForceUpdate && googleUpdateFrequency != 0) + { + string setting_String = PersistentStorage.GetSetting_String("LastGoogleUpdate_" + sourcePlayerPrefName, ""); + try + { + if (DateTime.TryParse(setting_String, out var result)) + { + double totalDays = (DateTime.Now - result).TotalDays; + switch (googleUpdateFrequency) + { + case eGoogleUpdateFrequency.Daily: + if (totalDays < 1.0) + { + return; + } + break; + case eGoogleUpdateFrequency.Weekly: + if (totalDays < 8.0) + { + return; + } + break; + case eGoogleUpdateFrequency.Monthly: + if (totalDays < 31.0) + { + return; + } + break; + case eGoogleUpdateFrequency.OnlyOnce: + return; + case eGoogleUpdateFrequency.EveryOtherDay: + if (totalDays < 2.0) + { + return; + } + break; + } + } + } + catch (Exception) + { + } + } + PersistentStorage.SetSetting_String("LastGoogleUpdate_" + sourcePlayerPrefName, DateTime.Now.ToString()); + CoroutineManager.Start(Import_Google_Coroutine(ForceUpdate, justCheck)); + } + + private string GetSourcePlayerPrefName() + { + if (owner == null) + { + return null; + } + string text = (owner as UnityEngine.Object).name; + if (!string.IsNullOrEmpty(Google_SpreadsheetKey)) + { + text += Google_SpreadsheetKey; + } + if (Array.IndexOf(LocalizationManager.GlobalSources, (owner as UnityEngine.Object).name) >= 0) + { + return text; + } + return SceneManager.GetActiveScene().name + "_" + text; + } + + private IEnumerator Import_Google_Coroutine(bool forceUpdate, bool JustCheck) + { + UnityWebRequest www = Import_Google_CreateWWWcall(forceUpdate, JustCheck); + if (www == null) + { + yield break; + } + while (!www.isDone) + { + yield return null; + } + byte[] data = www.downloadHandler.data; + if (string.IsNullOrEmpty(www.error) && data != null) + { + string @string = Encoding.UTF8.GetString(data, 0, data.Length); + bool flag = string.IsNullOrEmpty(@string) || @string == "\"\""; + if (JustCheck) + { + if (!flag) + { + Debug.LogWarning("Spreadsheet is not up-to-date and Google Live Synchronization is enabled\nWhen playing in the device the Spreadsheet will be downloaded and translations may not behave as what you see in the editor.\nTo fix this, Import or Export replace to Google"); + GoogleLiveSyncIsUptoDate = false; + } + yield break; + } + if (!flag) + { + mDelayedGoogleData = @string; + switch (GoogleUpdateSynchronization) + { + case eGoogleUpdateSynchronization.AsSoonAsDownloaded: + ApplyDownloadedDataFromGoogle(); + break; + case eGoogleUpdateSynchronization.OnSceneLoaded: + SceneManager.sceneLoaded += ApplyDownloadedDataOnSceneLoaded; + break; + } + yield break; + } + } + if (this.Event_OnSourceUpdateFromGoogle != null) + { + this.Event_OnSourceUpdateFromGoogle(this, ReceivedNewData: false, www.error); + } + Debug.Log("Language Source was up-to-date with Google Spreadsheet"); + } + + private void ApplyDownloadedDataOnSceneLoaded(Scene scene, LoadSceneMode mode) + { + SceneManager.sceneLoaded -= ApplyDownloadedDataOnSceneLoaded; + ApplyDownloadedDataFromGoogle(); + } + + public void ApplyDownloadedDataFromGoogle() + { + if (string.IsNullOrEmpty(mDelayedGoogleData)) + { + return; + } + if (string.IsNullOrEmpty(Import_Google_Result(mDelayedGoogleData, eSpreadsheetUpdateMode.Replace, saveInPlayerPrefs: true))) + { + if (this.Event_OnSourceUpdateFromGoogle != null) + { + this.Event_OnSourceUpdateFromGoogle(this, ReceivedNewData: true, ""); + } + LocalizationManager.LocalizeAll(Force: true); + Debug.Log("Done Google Sync"); + } + else + { + if (this.Event_OnSourceUpdateFromGoogle != null) + { + this.Event_OnSourceUpdateFromGoogle(this, ReceivedNewData: false, ""); + } + Debug.Log("Done Google Sync: source was up-to-date"); + } + } + + public UnityWebRequest Import_Google_CreateWWWcall(bool ForceUpdate, bool justCheck) + { + if (!HasGoogleSpreadsheet()) + { + return null; + } + string text = PersistentStorage.GetSetting_String("I2SourceVersion_" + GetSourcePlayerPrefName(), Google_LastUpdatedVersion); + if (text.Length > 19) + { + text = string.Empty; + } + if (IsNewerVersion(text, Google_LastUpdatedVersion)) + { + Google_LastUpdatedVersion = text; + } + UnityWebRequest unityWebRequest = UnityWebRequest.Get(string.Format("{0}?key={1}&action=GetLanguageSource&version={2}", LocalizationManager.GetWebServiceURL(this), Google_SpreadsheetKey, ForceUpdate ? "0" : Google_LastUpdatedVersion)); + I2Utils.SendWebRequest(unityWebRequest); + return unityWebRequest; + } + + public bool HasGoogleSpreadsheet() + { + if (!string.IsNullOrEmpty(Google_WebServiceURL) && !string.IsNullOrEmpty(Google_SpreadsheetKey)) + { + return !string.IsNullOrEmpty(LocalizationManager.GetWebServiceURL(this)); + } + return false; + } + + public string Import_Google_Result(string JsonString, eSpreadsheetUpdateMode UpdateMode, bool saveInPlayerPrefs = false) + { + try + { + string empty = string.Empty; + if (string.IsNullOrEmpty(JsonString) || JsonString == "\"\"") + { + return empty; + } + int num = JsonString.IndexOf("version=", StringComparison.Ordinal); + int num2 = JsonString.IndexOf("script_version=", StringComparison.Ordinal); + if (num < 0 || num2 < 0) + { + return "Invalid Response from Google, Most likely the WebService needs to be updated"; + } + num += "version=".Length; + num2 += "script_version=".Length; + string text = JsonString.Substring(num, JsonString.IndexOf(",", num, StringComparison.Ordinal) - num); + int num3 = int.Parse(JsonString.Substring(num2, JsonString.IndexOf(",", num2, StringComparison.Ordinal) - num2)); + if (text.Length > 19) + { + text = string.Empty; + } + if (num3 != LocalizationManager.GetRequiredWebServiceVersion()) + { + return "The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version."; + } + if (saveInPlayerPrefs && !IsNewerVersion(Google_LastUpdatedVersion, text)) + { + return "LanguageSource is up-to-date"; + } + if (saveInPlayerPrefs) + { + string sourcePlayerPrefName = GetSourcePlayerPrefName(); + PersistentStorage.SaveFile(PersistentStorage.eFileType.Persistent, "I2Source_" + sourcePlayerPrefName + ".loc", "[i2e]" + StringObfucator.Encode(JsonString)); + PersistentStorage.SetSetting_String("I2SourceVersion_" + sourcePlayerPrefName, text); + PersistentStorage.ForceSaveSettings(); + } + Google_LastUpdatedVersion = text; + if (UpdateMode == eSpreadsheetUpdateMode.Replace) + { + ClearAllData(); + } + int num4 = JsonString.IndexOf("[i2category]", StringComparison.Ordinal); + while (num4 > 0) + { + num4 += "[i2category]".Length; + int num5 = JsonString.IndexOf("[/i2category]", num4, StringComparison.Ordinal); + string category = JsonString.Substring(num4, num5 - num4); + num5 += "[/i2category]".Length; + int num6 = JsonString.IndexOf("[/i2csv]", num5, StringComparison.Ordinal); + string i2CSVstring = JsonString.Substring(num5, num6 - num5); + num4 = JsonString.IndexOf("[i2category]", num6, StringComparison.Ordinal); + Import_I2CSV(category, i2CSVstring, UpdateMode); + if (UpdateMode == eSpreadsheetUpdateMode.Replace) + { + UpdateMode = eSpreadsheetUpdateMode.Merge; + } + } + GoogleLiveSyncIsUptoDate = true; + if (I2Utils.IsPlaying()) + { + SaveLanguages(unloadAll: true); + } + if (!string.IsNullOrEmpty(empty)) + { + Editor_SetDirty(); + } + return empty; + } + catch (Exception ex) + { + Debug.LogWarning(ex); + return ex.ToString(); + } + } + + public int GetLanguageIndex(string language, bool AllowDiscartingRegion = true, bool SkipDisabled = true) + { + int i = 0; + for (int count = mLanguages.Count; i < count; i++) + { + if ((!SkipDisabled || mLanguages[i].IsEnabled()) && string.Compare(mLanguages[i].Name, language, StringComparison.OrdinalIgnoreCase) == 0) + { + return i; + } + } + if (AllowDiscartingRegion) + { + int num = -1; + int num2 = 0; + int j = 0; + for (int count2 = mLanguages.Count; j < count2; j++) + { + if (!SkipDisabled || mLanguages[j].IsEnabled()) + { + int commonWordInLanguageNames = GetCommonWordInLanguageNames(mLanguages[j].Name, language); + if (commonWordInLanguageNames > num2) + { + num2 = commonWordInLanguageNames; + num = j; + } + } + } + if (num >= 0) + { + return num; + } + } + return -1; + } + + public LanguageData GetLanguageData(string language, bool AllowDiscartingRegion = true) + { + int languageIndex = GetLanguageIndex(language, AllowDiscartingRegion, SkipDisabled: false); + if (languageIndex >= 0) + { + return mLanguages[languageIndex]; + } + return null; + } + + public bool IsCurrentLanguage(int languageIndex) + { + return LocalizationManager.CurrentLanguage == mLanguages[languageIndex].Name; + } + + public int GetLanguageIndexFromCode(string Code, bool exactMatch = true, bool ignoreDisabled = false) + { + int i = 0; + for (int count = mLanguages.Count; i < count; i++) + { + if ((!ignoreDisabled || mLanguages[i].IsEnabled()) && string.Compare(mLanguages[i].Code, Code, StringComparison.OrdinalIgnoreCase) == 0) + { + return i; + } + } + if (!exactMatch) + { + int j = 0; + for (int count2 = mLanguages.Count; j < count2; j++) + { + if ((!ignoreDisabled || mLanguages[j].IsEnabled()) && string.Compare(mLanguages[j].Code, 0, Code, 0, 2, StringComparison.OrdinalIgnoreCase) == 0) + { + return j; + } + } + } + return -1; + } + + public static int GetCommonWordInLanguageNames(string Language1, string Language2) + { + if (string.IsNullOrEmpty(Language1) || string.IsNullOrEmpty(Language2)) + { + return 0; + } + char[] separator = "( )-/\\".ToCharArray(); + string[] array = Language1.ToLower().Split(separator); + string[] array2 = Language2.ToLower().Split(separator); + int num = 0; + string[] array3 = array; + foreach (string value in array3) + { + if (!string.IsNullOrEmpty(value) && array2.Contains(value)) + { + num++; + } + } + array3 = array2; + foreach (string value2 in array3) + { + if (!string.IsNullOrEmpty(value2) && array.Contains(value2)) + { + num++; + } + } + return num; + } + + public static bool AreTheSameLanguage(string Language1, string Language2) + { + Language1 = GetLanguageWithoutRegion(Language1); + Language2 = GetLanguageWithoutRegion(Language2); + return string.Compare(Language1, Language2, StringComparison.OrdinalIgnoreCase) == 0; + } + + public static string GetLanguageWithoutRegion(string Language) + { + int num = Language.IndexOfAny("(/\\[,{".ToCharArray()); + if (num < 0) + { + return Language; + } + return Language.Substring(0, num).Trim(); + } + + public void AddLanguage(string LanguageName) + { + AddLanguage(LanguageName, GoogleLanguages.GetLanguageCode(LanguageName)); + } + + public void AddLanguage(string LanguageName, string LanguageCode) + { + if (GetLanguageIndex(LanguageName, AllowDiscartingRegion: false) < 0) + { + LanguageData languageData = new LanguageData(); + languageData.Name = LanguageName; + languageData.Code = LanguageCode; + mLanguages.Add(languageData); + int count = mLanguages.Count; + int i = 0; + for (int count2 = mTerms.Count; i < count2; i++) + { + Array.Resize(ref mTerms[i].Languages, count); + Array.Resize(ref mTerms[i].Flags, count); + } + Editor_SetDirty(); + } + } + + public void RemoveLanguage(string LanguageName) + { + int languageIndex = GetLanguageIndex(LanguageName, AllowDiscartingRegion: false, SkipDisabled: false); + if (languageIndex < 0) + { + return; + } + int count = mLanguages.Count; + int i = 0; + for (int count2 = mTerms.Count; i < count2; i++) + { + for (int j = languageIndex + 1; j < count; j++) + { + mTerms[i].Languages[j - 1] = mTerms[i].Languages[j]; + mTerms[i].Flags[j - 1] = mTerms[i].Flags[j]; + } + Array.Resize(ref mTerms[i].Languages, count - 1); + Array.Resize(ref mTerms[i].Flags, count - 1); + } + mLanguages.RemoveAt(languageIndex); + Editor_SetDirty(); + } + + public List<string> GetLanguages(bool skipDisabled = true) + { + List<string> list = new List<string>(); + int i = 0; + for (int count = mLanguages.Count; i < count; i++) + { + if (!skipDisabled || mLanguages[i].IsEnabled()) + { + list.Add(mLanguages[i].Name); + } + } + return list; + } + + public List<string> GetLanguagesCode(bool allowRegions = true, bool skipDisabled = true) + { + List<string> list = new List<string>(); + int i = 0; + for (int count = mLanguages.Count; i < count; i++) + { + if (!skipDisabled || mLanguages[i].IsEnabled()) + { + string text = mLanguages[i].Code; + if (!allowRegions && text != null && text.Length > 2) + { + text = text.Substring(0, 2); + } + if (!string.IsNullOrEmpty(text) && !list.Contains(text)) + { + list.Add(text); + } + } + } + return list; + } + + public bool IsLanguageEnabled(string Language) + { + int languageIndex = GetLanguageIndex(Language, AllowDiscartingRegion: false); + if (languageIndex >= 0) + { + return mLanguages[languageIndex].IsEnabled(); + } + return false; + } + + public void EnableLanguage(string Language, bool bEnabled) + { + int languageIndex = GetLanguageIndex(Language, AllowDiscartingRegion: false, SkipDisabled: false); + if (languageIndex >= 0) + { + mLanguages[languageIndex].SetEnabled(bEnabled); + } + } + + public bool AllowUnloadingLanguages() + { + return _AllowUnloadingLanguages != eAllowUnloadLanguages.Never; + } + + private string GetSavedLanguageFileName(int languageIndex) + { + if (languageIndex < 0) + { + return null; + } + return "LangSource_" + GetSourcePlayerPrefName() + "_" + mLanguages[languageIndex].Name + ".loc"; + } + + public void LoadLanguage(int languageIndex, bool UnloadOtherLanguages, bool useFallback, bool onlyCurrentSpecialization, bool forceLoad) + { + if (!AllowUnloadingLanguages() || !PersistentStorage.CanAccessFiles()) + { + return; + } + if (languageIndex >= 0 && (forceLoad || !mLanguages[languageIndex].IsLoaded())) + { + string savedLanguageFileName = GetSavedLanguageFileName(languageIndex); + string text = PersistentStorage.LoadFile(PersistentStorage.eFileType.Temporal, savedLanguageFileName, logExceptions: false); + if (!string.IsNullOrEmpty(text)) + { + Import_Language_from_Cache(languageIndex, text, useFallback, onlyCurrentSpecialization); + mLanguages[languageIndex].SetLoaded(loaded: true); + } + } + if (!UnloadOtherLanguages || !I2Utils.IsPlaying()) + { + return; + } + for (int i = 0; i < mLanguages.Count; i++) + { + if (i != languageIndex) + { + UnloadLanguage(i); + } + } + } + + public void LoadAllLanguages(bool forceLoad = false) + { + for (int i = 0; i < mLanguages.Count; i++) + { + LoadLanguage(i, UnloadOtherLanguages: false, useFallback: false, onlyCurrentSpecialization: false, forceLoad); + } + } + + public void UnloadLanguage(int languageIndex) + { + if (!AllowUnloadingLanguages() || !PersistentStorage.CanAccessFiles() || !I2Utils.IsPlaying() || !mLanguages[languageIndex].IsLoaded() || !mLanguages[languageIndex].CanBeUnloaded() || IsCurrentLanguage(languageIndex) || !PersistentStorage.HasFile(PersistentStorage.eFileType.Temporal, GetSavedLanguageFileName(languageIndex))) + { + return; + } + foreach (TermData mTerm in mTerms) + { + mTerm.Languages[languageIndex] = null; + } + mLanguages[languageIndex].SetLoaded(loaded: false); + } + + public void SaveLanguages(bool unloadAll, PersistentStorage.eFileType fileLocation = PersistentStorage.eFileType.Temporal) + { + if (!AllowUnloadingLanguages() || !PersistentStorage.CanAccessFiles()) + { + return; + } + for (int i = 0; i < mLanguages.Count; i++) + { + string text = Export_Language_to_Cache(i, IsCurrentLanguage(i)); + if (!string.IsNullOrEmpty(text)) + { + PersistentStorage.SaveFile(PersistentStorage.eFileType.Temporal, GetSavedLanguageFileName(i), text); + } + } + if (!unloadAll) + { + return; + } + for (int j = 0; j < mLanguages.Count; j++) + { + if (unloadAll && !IsCurrentLanguage(j)) + { + UnloadLanguage(j); + } + } + } + + public bool HasUnloadedLanguages() + { + for (int i = 0; i < mLanguages.Count; i++) + { + if (!mLanguages[i].IsLoaded()) + { + return true; + } + } + return false; + } + + public List<string> GetCategories(bool OnlyMainCategory = false, List<string> Categories = null) + { + if (Categories == null) + { + Categories = new List<string>(); + } + foreach (TermData mTerm in mTerms) + { + string categoryFromFullTerm = GetCategoryFromFullTerm(mTerm.Term, OnlyMainCategory); + if (!Categories.Contains(categoryFromFullTerm)) + { + Categories.Add(categoryFromFullTerm); + } + } + Categories.Sort(); + return Categories; + } + + public static string GetKeyFromFullTerm(string FullTerm, bool OnlyMainCategory = false) + { + int num = (OnlyMainCategory ? FullTerm.IndexOfAny(CategorySeparators) : FullTerm.LastIndexOfAny(CategorySeparators)); + if (num >= 0) + { + return FullTerm.Substring(num + 1); + } + return FullTerm; + } + + public static string GetCategoryFromFullTerm(string FullTerm, bool OnlyMainCategory = false) + { + int num = (OnlyMainCategory ? FullTerm.IndexOfAny(CategorySeparators) : FullTerm.LastIndexOfAny(CategorySeparators)); + if (num >= 0) + { + return FullTerm.Substring(0, num); + } + return EmptyCategory; + } + + public static void DeserializeFullTerm(string FullTerm, out string Key, out string Category, bool OnlyMainCategory = false) + { + int num = (OnlyMainCategory ? FullTerm.IndexOfAny(CategorySeparators) : FullTerm.LastIndexOfAny(CategorySeparators)); + if (num < 0) + { + Category = EmptyCategory; + Key = FullTerm; + } + else + { + Category = FullTerm.Substring(0, num); + Key = FullTerm.Substring(num + 1); + } + } + + public void UpdateDictionary(bool force = false) + { + if (force || mDictionary == null || mDictionary.Count != mTerms.Count) + { + StringComparer stringComparer = (CaseInsensitiveTerms ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); + if (mDictionary.Comparer != stringComparer) + { + mDictionary = new Dictionary<string, TermData>(stringComparer); + } + else + { + mDictionary.Clear(); + } + int i = 0; + for (int count = mTerms.Count; i < count; i++) + { + TermData termData = mTerms[i]; + ValidateFullTerm(ref termData.Term); + mDictionary[termData.Term] = mTerms[i]; + mTerms[i].Validate(); + } + if (I2Utils.IsPlaying()) + { + SaveLanguages(unloadAll: true); + } + } + } + + public string GetTranslation(string term, string overrideLanguage = null, string overrideSpecialization = null, bool skipDisabled = false, bool allowCategoryMistmatch = false) + { + TryGetTranslation(term, out var Translation, overrideLanguage, overrideSpecialization, skipDisabled, allowCategoryMistmatch); + return Translation; + } + + public bool TryGetTranslation(string term, out string Translation, string overrideLanguage = null, string overrideSpecialization = null, bool skipDisabled = false, bool allowCategoryMistmatch = false) + { + int languageIndex = GetLanguageIndex((overrideLanguage == null) ? LocalizationManager.CurrentLanguage : overrideLanguage, AllowDiscartingRegion: true, SkipDisabled: false); + if (languageIndex >= 0 && (!skipDisabled || mLanguages[languageIndex].IsEnabled())) + { + TermData termData = GetTermData(term, allowCategoryMistmatch); + if (termData != null) + { + Translation = termData.GetTranslation(languageIndex, overrideSpecialization, editMode: true); + if (Translation == "---") + { + Translation = string.Empty; + return true; + } + if (!string.IsNullOrEmpty(Translation)) + { + return true; + } + Translation = null; + } + if (OnMissingTranslation == MissingTranslationAction.ShowWarning) + { + Translation = "<!-Missing Translation [" + term + "]-!>"; + Debug.LogWarning("Missing Translation for '" + term + "'", Localize.CurrentLocalizeComponent); + return false; + } + if (OnMissingTranslation == MissingTranslationAction.Fallback && termData != null) + { + return TryGetFallbackTranslation(termData, out Translation, languageIndex, overrideSpecialization, skipDisabled); + } + if (OnMissingTranslation == MissingTranslationAction.Empty) + { + Translation = string.Empty; + return false; + } + if (OnMissingTranslation == MissingTranslationAction.ShowTerm) + { + Translation = term; + return false; + } + } + Translation = null; + return false; + } + + private bool TryGetFallbackTranslation(TermData termData, out string Translation, int langIndex, string overrideSpecialization = null, bool skipDisabled = false) + { + string text = mLanguages[langIndex].Code; + if (!string.IsNullOrEmpty(text)) + { + if (text.Contains("-")) + { + text = text.Substring(0, text.IndexOf('-')); + } + for (int i = 0; i < mLanguages.Count; i++) + { + if (i != langIndex && mLanguages[i].Code.StartsWith(text, StringComparison.Ordinal) && (!skipDisabled || mLanguages[i].IsEnabled())) + { + Translation = termData.GetTranslation(i, overrideSpecialization, editMode: true); + if (!string.IsNullOrEmpty(Translation)) + { + return true; + } + } + } + } + for (int j = 0; j < mLanguages.Count; j++) + { + if (j != langIndex && (!skipDisabled || mLanguages[j].IsEnabled()) && (text == null || !mLanguages[j].Code.StartsWith(text, StringComparison.Ordinal))) + { + Translation = termData.GetTranslation(j, overrideSpecialization, editMode: true); + if (!string.IsNullOrEmpty(Translation)) + { + return true; + } + } + } + Translation = null; + return false; + } + + public TermData AddTerm(string term) + { + return AddTerm(term, eTermType.Text); + } + + public TermData GetTermData(string term, bool allowCategoryMistmatch = false) + { + if (string.IsNullOrEmpty(term)) + { + return null; + } + if (mDictionary.Count == 0) + { + UpdateDictionary(); + } + if (mDictionary.TryGetValue(term, out var value)) + { + return value; + } + TermData termData = null; + if (allowCategoryMistmatch) + { + string keyFromFullTerm = GetKeyFromFullTerm(term); + { + foreach (KeyValuePair<string, TermData> item in mDictionary) + { + if (item.Value.IsTerm(keyFromFullTerm, allowCategoryMistmatch: true)) + { + if (termData != null) + { + return null; + } + termData = item.Value; + } + } + return termData; + } + } + return termData; + } + + public bool ContainsTerm(string term) + { + return GetTermData(term) != null; + } + + public List<string> GetTermsList(string Category = null) + { + if (mDictionary.Count != mTerms.Count) + { + UpdateDictionary(); + } + if (string.IsNullOrEmpty(Category)) + { + return new List<string>(mDictionary.Keys); + } + List<string> list = new List<string>(); + for (int i = 0; i < mTerms.Count; i++) + { + TermData termData = mTerms[i]; + if (GetCategoryFromFullTerm(termData.Term) == Category) + { + list.Add(termData.Term); + } + } + return list; + } + + public TermData AddTerm(string NewTerm, eTermType termType, bool SaveSource = true) + { + ValidateFullTerm(ref NewTerm); + NewTerm = NewTerm.Trim(); + if (mLanguages.Count == 0) + { + AddLanguage("English", "en"); + } + TermData termData = GetTermData(NewTerm); + if (termData == null) + { + termData = new TermData(); + termData.Term = NewTerm; + termData.TermType = termType; + termData.Languages = new string[mLanguages.Count]; + termData.Flags = new byte[mLanguages.Count]; + mTerms.Add(termData); + mDictionary.Add(NewTerm, termData); + } + return termData; + } + + public void RemoveTerm(string term) + { + int i = 0; + for (int count = mTerms.Count; i < count; i++) + { + if (mTerms[i].Term == term) + { + mTerms.RemoveAt(i); + mDictionary.Remove(term); + break; + } + } + } + + public static void ValidateFullTerm(ref string Term) + { + Term = Term.Replace('\\', '/'); + Term = Term.Trim(); + if (Term.StartsWith(EmptyCategory, StringComparison.Ordinal) && Term.Length > EmptyCategory.Length && Term[EmptyCategory.Length] == '/') + { + Term = Term.Substring(EmptyCategory.Length + 1); + } + Term = I2Utils.GetValidTermName(Term, allowCategory: true); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationManager.cs new file mode 100644 index 0000000..49292c5 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationManager.cs @@ -0,0 +1,1056 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; +using UnityEngine; + +namespace I2.Loc; + +public static class LocalizationManager +{ + public delegate bool FnCustomApplyLocalizationParams(ref string translation, _GetParam getParam, bool allowLocalizedParameters); + + public delegate object _GetParam(string param); + + public delegate void OnLocalizeCallback(); + + private static string mCurrentLanguage; + + private static string mLanguageCode; + + private static CultureInfo mCurrentCulture; + + private static bool mChangeCultureInfo; + + public static bool IsRight2Left; + + public static bool HasJoinedWords; + + public static List<ILocalizationParamsManager> ParamManagers = new List<ILocalizationParamsManager>(); + + public static FnCustomApplyLocalizationParams CustomApplyLocalizationParams; + + private static string[] LanguagesRTL = new string[21] + { + "ar-DZ", "ar", "ar-BH", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", + "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-AE", "ar-YE", "fa", "he", "ur", + "ji" + }; + + public static List<LanguageSourceData> Sources = new List<LanguageSourceData>(); + + public static string[] GlobalSources = new string[1] { "I2Languages" }; + + public static Func<LanguageSourceData, bool> Callback_AllowSyncFromGoogle = null; + + private static string mCurrentDeviceLanguage; + + public static List<ILocalizeTargetDescriptor> mLocalizeTargets = new List<ILocalizeTargetDescriptor>(); + + private static bool mLocalizeIsScheduled; + + private static bool mLocalizeIsScheduledWithForcedValue; + + public static bool HighlightLocalizedTargets = false; + + public static string CurrentLanguage + { + get + { + InitializeIfNeeded(); + return mCurrentLanguage; + } + set + { + InitializeIfNeeded(); + string supportedLanguage = GetSupportedLanguage(value); + if (!string.IsNullOrEmpty(supportedLanguage) && mCurrentLanguage != supportedLanguage) + { + SetLanguageAndCode(supportedLanguage, GetLanguageCode(supportedLanguage)); + } + } + } + + public static string CurrentLanguageCode + { + get + { + InitializeIfNeeded(); + return mLanguageCode; + } + set + { + InitializeIfNeeded(); + if (mLanguageCode != value) + { + string languageFromCode = GetLanguageFromCode(value); + if (!string.IsNullOrEmpty(languageFromCode)) + { + SetLanguageAndCode(languageFromCode, value); + } + } + } + } + + public static string CurrentRegion + { + get + { + string currentLanguage = CurrentLanguage; + int num = currentLanguage.IndexOfAny("/\\".ToCharArray()); + if (num > 0) + { + return currentLanguage.Substring(num + 1); + } + num = currentLanguage.IndexOfAny("[(".ToCharArray()); + int num2 = currentLanguage.LastIndexOfAny("])".ToCharArray()); + if (num > 0 && num != num2) + { + return currentLanguage.Substring(num + 1, num2 - num - 1); + } + return string.Empty; + } + set + { + string text = CurrentLanguage; + int num = text.IndexOfAny("/\\".ToCharArray()); + if (num > 0) + { + CurrentLanguage = text.Substring(num + 1) + value; + return; + } + num = text.IndexOfAny("[(".ToCharArray()); + int num2 = text.LastIndexOfAny("])".ToCharArray()); + if (num > 0 && num != num2) + { + text = text.Substring(num); + } + CurrentLanguage = text + "(" + value + ")"; + } + } + + public static string CurrentRegionCode + { + get + { + string currentLanguageCode = CurrentLanguageCode; + int num = currentLanguageCode.IndexOfAny(" -_/\\".ToCharArray()); + if (num >= 0) + { + return currentLanguageCode.Substring(num + 1); + } + return string.Empty; + } + set + { + string text = CurrentLanguageCode; + int num = text.IndexOfAny(" -_/\\".ToCharArray()); + if (num > 0) + { + text = text.Substring(0, num); + } + CurrentLanguageCode = text + "-" + value; + } + } + + public static CultureInfo CurrentCulture => mCurrentCulture; + + public static event OnLocalizeCallback OnLocalizeEvent; + + public static void InitializeIfNeeded() + { + if (string.IsNullOrEmpty(mCurrentLanguage) || Sources.Count == 0) + { + AutoLoadGlobalParamManagers(); + UpdateSources(); + SelectStartupLanguage(); + } + } + + public static string GetVersion() + { + return "2.8.20 f2"; + } + + public static int GetRequiredWebServiceVersion() + { + return 5; + } + + public static string GetWebServiceURL(LanguageSourceData source = null) + { + if (source != null && !string.IsNullOrEmpty(source.Google_WebServiceURL)) + { + return source.Google_WebServiceURL; + } + InitializeIfNeeded(); + for (int i = 0; i < Sources.Count; i++) + { + if (Sources[i] != null && !string.IsNullOrEmpty(Sources[i].Google_WebServiceURL)) + { + return Sources[i].Google_WebServiceURL; + } + } + return string.Empty; + } + + public static void SetLanguageAndCode(string LanguageName, string LanguageCode, bool RememberLanguage = true, bool Force = false) + { + if (mCurrentLanguage != LanguageName || mLanguageCode != LanguageCode || Force) + { + if (RememberLanguage) + { + PersistentStorage.SetSetting_String("I2 Language", LanguageName); + } + mCurrentLanguage = LanguageName; + mLanguageCode = LanguageCode; + mCurrentCulture = CreateCultureForCode(LanguageCode); + if (mChangeCultureInfo) + { + SetCurrentCultureInfo(); + } + IsRight2Left = IsRTL(mLanguageCode); + HasJoinedWords = GoogleLanguages.LanguageCode_HasJoinedWord(mLanguageCode); + LocalizeAll(Force); + } + } + + private static CultureInfo CreateCultureForCode(string code) + { + try + { + return CultureInfo.CreateSpecificCulture(code); + } + catch (Exception) + { + return CultureInfo.InvariantCulture; + } + } + + public static void EnableChangingCultureInfo(bool bEnable) + { + if (!mChangeCultureInfo && bEnable) + { + SetCurrentCultureInfo(); + } + mChangeCultureInfo = bEnable; + } + + private static void SetCurrentCultureInfo() + { + Thread.CurrentThread.CurrentCulture = mCurrentCulture; + } + + private static void SelectStartupLanguage() + { + if (Sources.Count == 0) + { + return; + } + string setting_String = PersistentStorage.GetSetting_String("I2 Language", string.Empty); + string currentDeviceLanguage = GetCurrentDeviceLanguage(); + if (!string.IsNullOrEmpty(setting_String) && HasLanguage(setting_String, AllowDiscartingRegion: true, Initialize: false)) + { + SetLanguageAndCode(setting_String, GetLanguageCode(setting_String)); + return; + } + if (!Sources[0].IgnoreDeviceLanguage) + { + string supportedLanguage = GetSupportedLanguage(currentDeviceLanguage, ignoreDisabled: true); + if (!string.IsNullOrEmpty(supportedLanguage)) + { + SetLanguageAndCode(supportedLanguage, GetLanguageCode(supportedLanguage), RememberLanguage: false); + return; + } + } + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + if (Sources[i].mLanguages.Count <= 0) + { + continue; + } + for (int j = 0; j < Sources[i].mLanguages.Count; j++) + { + if (Sources[i].mLanguages[j].IsEnabled()) + { + SetLanguageAndCode(Sources[i].mLanguages[j].Name, Sources[i].mLanguages[j].Code, RememberLanguage: false); + return; + } + } + } + } + + public static bool HasLanguage(string Language, bool AllowDiscartingRegion = true, bool Initialize = true, bool SkipDisabled = true) + { + if (Initialize) + { + InitializeIfNeeded(); + } + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + if (Sources[i].GetLanguageIndex(Language, AllowDiscartingRegion: false, SkipDisabled) >= 0) + { + return true; + } + } + if (AllowDiscartingRegion) + { + int j = 0; + for (int count2 = Sources.Count; j < count2; j++) + { + if (Sources[j].GetLanguageIndex(Language, AllowDiscartingRegion: true, SkipDisabled) >= 0) + { + return true; + } + } + } + return false; + } + + public static string GetSupportedLanguage(string Language, bool ignoreDisabled = false) + { + string languageCode = GoogleLanguages.GetLanguageCode(Language); + if (!string.IsNullOrEmpty(languageCode)) + { + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + int languageIndexFromCode = Sources[i].GetLanguageIndexFromCode(languageCode, exactMatch: true, ignoreDisabled); + if (languageIndexFromCode >= 0) + { + return Sources[i].mLanguages[languageIndexFromCode].Name; + } + } + int j = 0; + for (int count2 = Sources.Count; j < count2; j++) + { + int languageIndexFromCode2 = Sources[j].GetLanguageIndexFromCode(languageCode, exactMatch: false, ignoreDisabled); + if (languageIndexFromCode2 >= 0) + { + return Sources[j].mLanguages[languageIndexFromCode2].Name; + } + } + } + int k = 0; + for (int count3 = Sources.Count; k < count3; k++) + { + int languageIndex = Sources[k].GetLanguageIndex(Language, AllowDiscartingRegion: false, ignoreDisabled); + if (languageIndex >= 0) + { + return Sources[k].mLanguages[languageIndex].Name; + } + } + int l = 0; + for (int count4 = Sources.Count; l < count4; l++) + { + int languageIndex2 = Sources[l].GetLanguageIndex(Language, AllowDiscartingRegion: true, ignoreDisabled); + if (languageIndex2 >= 0) + { + return Sources[l].mLanguages[languageIndex2].Name; + } + } + return string.Empty; + } + + public static string GetLanguageCode(string Language) + { + if (Sources.Count == 0) + { + UpdateSources(); + } + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + int languageIndex = Sources[i].GetLanguageIndex(Language); + if (languageIndex >= 0) + { + return Sources[i].mLanguages[languageIndex].Code; + } + } + return string.Empty; + } + + public static string GetLanguageFromCode(string Code, bool exactMatch = true) + { + if (Sources.Count == 0) + { + UpdateSources(); + } + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + int languageIndexFromCode = Sources[i].GetLanguageIndexFromCode(Code, exactMatch); + if (languageIndexFromCode >= 0) + { + return Sources[i].mLanguages[languageIndexFromCode].Name; + } + } + return string.Empty; + } + + public static List<string> GetAllLanguages(bool SkipDisabled = true) + { + if (Sources.Count == 0) + { + UpdateSources(); + } + List<string> Languages = new List<string>(); + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + Languages.AddRange(from x in Sources[i].GetLanguages(SkipDisabled) + where !Languages.Contains(x) + select x); + } + return Languages; + } + + public static List<string> GetAllLanguagesCode(bool allowRegions = true, bool SkipDisabled = true) + { + List<string> Languages = new List<string>(); + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + Languages.AddRange(from x in Sources[i].GetLanguagesCode(allowRegions, SkipDisabled) + where !Languages.Contains(x) + select x); + } + return Languages; + } + + public static bool IsLanguageEnabled(string Language) + { + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + if (!Sources[i].IsLanguageEnabled(Language)) + { + return false; + } + } + return true; + } + + private static void LoadCurrentLanguage() + { + for (int i = 0; i < Sources.Count; i++) + { + int languageIndex = Sources[i].GetLanguageIndex(mCurrentLanguage, AllowDiscartingRegion: true, SkipDisabled: false); + Sources[i].LoadLanguage(languageIndex, UnloadOtherLanguages: true, useFallback: true, onlyCurrentSpecialization: true, forceLoad: false); + } + } + + public static void PreviewLanguage(string NewLanguage) + { + mCurrentLanguage = NewLanguage; + mLanguageCode = GetLanguageCode(mCurrentLanguage); + IsRight2Left = IsRTL(mLanguageCode); + HasJoinedWords = GoogleLanguages.LanguageCode_HasJoinedWord(mLanguageCode); + } + + public static void AutoLoadGlobalParamManagers() + { + LocalizationParamsManager[] array = UnityEngine.Object.FindObjectsOfType<LocalizationParamsManager>(); + foreach (LocalizationParamsManager localizationParamsManager in array) + { + if (localizationParamsManager._IsGlobalManager && !ParamManagers.Contains(localizationParamsManager)) + { + Debug.Log(localizationParamsManager); + ParamManagers.Add(localizationParamsManager); + } + } + } + + public static void ApplyLocalizationParams(ref string translation, bool allowLocalizedParameters = true) + { + ApplyLocalizationParams(ref translation, (string p) => GetLocalizationParam(p, null), allowLocalizedParameters); + } + + public static void ApplyLocalizationParams(ref string translation, GameObject root, bool allowLocalizedParameters = true) + { + ApplyLocalizationParams(ref translation, (string p) => GetLocalizationParam(p, root), allowLocalizedParameters); + } + + public static void ApplyLocalizationParams(ref string translation, Dictionary<string, object> parameters, bool allowLocalizedParameters = true) + { + ApplyLocalizationParams(ref translation, delegate(string p) + { + object value = null; + return parameters.TryGetValue(p, out value) ? value : null; + }, allowLocalizedParameters); + } + + public static void ApplyLocalizationParams(ref string translation, _GetParam getParam, bool allowLocalizedParameters = true) + { + if (translation == null || (CustomApplyLocalizationParams != null && CustomApplyLocalizationParams(ref translation, getParam, allowLocalizedParameters))) + { + return; + } + string text = null; + int num = 0; + int length = translation.Length; + int num2 = 0; + while (num2 >= 0 && num2 < translation.Length) + { + int num3 = translation.IndexOf("{[", num2, StringComparison.Ordinal); + if (num3 < 0) + { + break; + } + int num4 = translation.IndexOf("]}", num3, StringComparison.Ordinal); + if (num4 < 0) + { + break; + } + int num5 = translation.IndexOf("{[", num3 + 1, StringComparison.Ordinal); + if (num5 > 0 && num5 < num4) + { + num2 = num5; + continue; + } + int num6 = ((translation[num3 + 2] == '#') ? 3 : 2); + string param = translation.Substring(num3 + num6, num4 - num3 - num6); + string text2 = (string)getParam(param); + if (text2 != null) + { + if (allowLocalizedParameters) + { + LanguageSourceData source; + TermData termData = GetTermData(text2, out source); + if (termData != null) + { + int languageIndex = source.GetLanguageIndex(CurrentLanguage); + if (languageIndex >= 0) + { + text2 = termData.GetTranslation(languageIndex); + } + } + } + string oldValue = translation.Substring(num3, num4 - num3 + 2); + translation = translation.Replace(oldValue, text2); + int result = 0; + if (int.TryParse(text2, out result)) + { + text = GoogleLanguages.GetPluralType(CurrentLanguageCode, result).ToString(); + } + num2 = num3 + text2.Length; + } + else + { + num2 = num4 + 2; + } + } + if (text != null) + { + string text3 = "[i2p_" + text + "]"; + num = translation.IndexOf(text3, StringComparison.OrdinalIgnoreCase); + num = ((num >= 0) ? (num + text3.Length) : 0); + length = translation.IndexOf("[i2p_", num + 1, StringComparison.OrdinalIgnoreCase); + if (length < 0) + { + length = translation.Length; + } + translation = translation.Substring(num, length - num); + } + } + + internal static string GetLocalizationParam(string ParamName, GameObject root) + { + string text = null; + if ((bool)root) + { + MonoBehaviour[] components = root.GetComponents<MonoBehaviour>(); + int i = 0; + for (int num = components.Length; i < num; i++) + { + if (components[i] is ILocalizationParamsManager localizationParamsManager && components[i].enabled) + { + text = localizationParamsManager.GetParameterValue(ParamName); + if (text != null) + { + return text; + } + } + } + } + int j = 0; + for (int count = ParamManagers.Count; j < count; j++) + { + text = ParamManagers[j].GetParameterValue(ParamName); + if (text != null) + { + return text; + } + } + return null; + } + + private static string GetPluralType(MatchCollection matches, string langCode, _GetParam getParam) + { + int i = 0; + for (int count = matches.Count; i < count; i++) + { + Match match = matches[i]; + string value = match.Groups[match.Groups.Count - 1].Value; + string text = (string)getParam(value); + if (text != null) + { + int result = 0; + if (int.TryParse(text, out result)) + { + return GoogleLanguages.GetPluralType(langCode, result).ToString(); + } + } + } + return null; + } + + public static string ApplyRTLfix(string line) + { + return ApplyRTLfix(line, 0, ignoreNumbers: true); + } + + public static string ApplyRTLfix(string line, int maxCharacters, bool ignoreNumbers) + { + if (string.IsNullOrEmpty(line)) + { + return line; + } + char c = line[0]; + if (c == '!' || c == '.' || c == '?') + { + line = line.Substring(1) + c; + } + int tagStart = -1; + int num = 0; + int num2 = 40000; + num = 0; + List<string> list = new List<string>(); + while (I2Utils.FindNextTag(line, num, out tagStart, out num)) + { + string text = "@@" + (char)(num2 + list.Count) + "@@"; + list.Add(line.Substring(tagStart, num - tagStart + 1)); + line = line.Substring(0, tagStart) + text + line.Substring(num + 1); + num = tagStart + 5; + } + line = line.Replace("\r\n", "\n"); + line = I2Utils.SplitLine(line, maxCharacters); + line = RTLFixer.Fix(line, showTashkeel: true, !ignoreNumbers); + for (int i = 0; i < list.Count; i++) + { + int length = line.Length; + for (int j = 0; j < length - 4; j++) + { + if (line[j] == '@' && line[j + 1] == '@' && line[j + 2] >= num2 && line[j + 3] == '@' && line[j + 4] == '@') + { + int num3 = line[j + 2] - num2; + num3 = ((num3 % 2 != 0) ? (num3 - 1) : (num3 + 1)); + if (num3 >= list.Count) + { + num3 = list.Count - 1; + } + line = line.Substring(0, j) + list[num3] + line.Substring(j + 5); + break; + } + } + } + return line; + } + + public static string FixRTL_IfNeeded(string text, int maxCharacters = 0, bool ignoreNumber = false) + { + if (IsRight2Left) + { + return ApplyRTLfix(text, maxCharacters, ignoreNumber); + } + return text; + } + + public static bool IsRTL(string Code) + { + return Array.IndexOf(LanguagesRTL, Code) >= 0; + } + + public static bool UpdateSources() + { + UnregisterDeletededSources(); + RegisterSourceInResources(); + RegisterSceneSources(); + return Sources.Count > 0; + } + + private static void UnregisterDeletededSources() + { + for (int num = Sources.Count - 1; num >= 0; num--) + { + if (Sources[num] == null) + { + RemoveSource(Sources[num]); + } + } + } + + private static void RegisterSceneSources() + { + LanguageSource[] array = (LanguageSource[])Resources.FindObjectsOfTypeAll(typeof(LanguageSource)); + foreach (LanguageSource languageSource in array) + { + if (!Sources.Contains(languageSource.mSource)) + { + if (languageSource.mSource.owner == null) + { + languageSource.mSource.owner = languageSource; + } + AddSource(languageSource.mSource); + } + } + } + + private static void RegisterSourceInResources() + { + string[] globalSources = GlobalSources; + foreach (string name in globalSources) + { + LanguageSourceAsset asset = ResourceManager.pInstance.GetAsset<LanguageSourceAsset>(name); + if ((bool)asset && !Sources.Contains(asset.mSource)) + { + if (!asset.mSource.mIsGlobalSource) + { + asset.mSource.mIsGlobalSource = true; + } + asset.mSource.owner = asset; + AddSource(asset.mSource); + } + } + } + + private static bool AllowSyncFromGoogle(LanguageSourceData Source) + { + if (Callback_AllowSyncFromGoogle == null) + { + return true; + } + return Callback_AllowSyncFromGoogle(Source); + } + + internal static void AddSource(LanguageSourceData Source) + { + if (Sources.Contains(Source)) + { + return; + } + Sources.Add(Source); + if (Source.HasGoogleSpreadsheet() && Source.GoogleUpdateFrequency != LanguageSourceData.eGoogleUpdateFrequency.Never && AllowSyncFromGoogle(Source)) + { + Source.Import_Google_FromCache(); + bool justCheck = false; + if (Source.GoogleUpdateDelay > 0f) + { + CoroutineManager.Start(Delayed_Import_Google(Source, Source.GoogleUpdateDelay, justCheck)); + } + else + { + Source.Import_Google(ForceUpdate: false, justCheck); + } + } + for (int i = 0; i < Source.mLanguages.Count; i++) + { + Source.mLanguages[i].SetLoaded(loaded: true); + } + if (Source.mDictionary.Count == 0) + { + Source.UpdateDictionary(force: true); + } + } + + private static IEnumerator Delayed_Import_Google(LanguageSourceData source, float delay, bool justCheck) + { + yield return new WaitForSeconds(delay); + source?.Import_Google(ForceUpdate: false, justCheck); + } + + internal static void RemoveSource(LanguageSourceData Source) + { + Sources.Remove(Source); + } + + public static bool IsGlobalSource(string SourceName) + { + return Array.IndexOf(GlobalSources, SourceName) >= 0; + } + + public static LanguageSourceData GetSourceContaining(string term, bool fallbackToFirst = true) + { + if (!string.IsNullOrEmpty(term)) + { + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + if (Sources[i].GetTermData(term) != null) + { + return Sources[i]; + } + } + } + if (!fallbackToFirst || Sources.Count <= 0) + { + return null; + } + return Sources[0]; + } + + public static UnityEngine.Object FindAsset(string value) + { + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + UnityEngine.Object @object = Sources[i].FindAsset(value); + if ((bool)@object) + { + return @object; + } + } + return null; + } + + public static void ApplyDownloadedDataFromGoogle() + { + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + Sources[i].ApplyDownloadedDataFromGoogle(); + } + } + + public static string GetCurrentDeviceLanguage(bool force = false) + { + if (force || string.IsNullOrEmpty(mCurrentDeviceLanguage)) + { + DetectDeviceLanguage(); + } + return mCurrentDeviceLanguage; + } + + private static void DetectDeviceLanguage() + { + mCurrentDeviceLanguage = Application.systemLanguage.ToString(); + if (mCurrentDeviceLanguage == "ChineseSimplified") + { + mCurrentDeviceLanguage = "Chinese (Simplified)"; + } + if (mCurrentDeviceLanguage == "ChineseTraditional") + { + mCurrentDeviceLanguage = "Chinese (Traditional)"; + } + } + + public static void RegisterTarget(ILocalizeTargetDescriptor desc) + { + if (mLocalizeTargets.FindIndex((ILocalizeTargetDescriptor x) => x.Name == desc.Name) != -1) + { + return; + } + for (int i = 0; i < mLocalizeTargets.Count; i++) + { + if (mLocalizeTargets[i].Priority > desc.Priority) + { + mLocalizeTargets.Insert(i, desc); + return; + } + } + mLocalizeTargets.Add(desc); + } + + public static string GetTranslation(string Term, bool FixForRTL = true, int maxLineLengthForRTL = 0, bool ignoreRTLnumbers = true, bool applyParameters = false, GameObject localParametersRoot = null, string overrideLanguage = null, bool allowLocalizedParameters = true) + { + string Translation = null; + TryGetTranslation(Term, out Translation, FixForRTL, maxLineLengthForRTL, ignoreRTLnumbers, applyParameters, localParametersRoot, overrideLanguage, allowLocalizedParameters); + return Translation; + } + + public static string GetTermTranslation(string Term, bool FixForRTL = true, int maxLineLengthForRTL = 0, bool ignoreRTLnumbers = true, bool applyParameters = false, GameObject localParametersRoot = null, string overrideLanguage = null, bool allowLocalizedParameters = true) + { + return GetTranslation(Term, FixForRTL, maxLineLengthForRTL, ignoreRTLnumbers, applyParameters, localParametersRoot, overrideLanguage, allowLocalizedParameters); + } + + public static bool TryGetTranslation(string Term, out string Translation, bool FixForRTL = true, int maxLineLengthForRTL = 0, bool ignoreRTLnumbers = true, bool applyParameters = false, GameObject localParametersRoot = null, string overrideLanguage = null, bool allowLocalizedParameters = true) + { + Translation = null; + if (string.IsNullOrEmpty(Term)) + { + return false; + } + InitializeIfNeeded(); + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + if (Sources[i].TryGetTranslation(Term, out Translation, overrideLanguage)) + { + if (applyParameters) + { + ApplyLocalizationParams(ref Translation, localParametersRoot, allowLocalizedParameters); + } + if (IsRight2Left && FixForRTL) + { + Translation = ApplyRTLfix(Translation, maxLineLengthForRTL, ignoreRTLnumbers); + } + return true; + } + } + return false; + } + + public static T GetTranslatedObject<T>(string AssetName, Localize optionalLocComp = null) where T : UnityEngine.Object + { + if (optionalLocComp != null) + { + return optionalLocComp.FindTranslatedObject<T>(AssetName); + } + T val = FindAsset(AssetName) as T; + if ((bool)(UnityEngine.Object)val) + { + return val; + } + return ResourceManager.pInstance.GetAsset<T>(AssetName); + } + + public static T GetTranslatedObjectByTermName<T>(string Term, Localize optionalLocComp = null) where T : UnityEngine.Object + { + return GetTranslatedObject<T>(GetTranslation(Term, FixForRTL: false)); + } + + public static string GetAppName(string languageCode) + { + if (!string.IsNullOrEmpty(languageCode)) + { + for (int i = 0; i < Sources.Count; i++) + { + if (string.IsNullOrEmpty(Sources[i].mTerm_AppName)) + { + continue; + } + int languageIndexFromCode = Sources[i].GetLanguageIndexFromCode(languageCode, exactMatch: false); + if (languageIndexFromCode < 0) + { + continue; + } + TermData termData = Sources[i].GetTermData(Sources[i].mTerm_AppName); + if (termData != null) + { + string translation = termData.GetTranslation(languageIndexFromCode); + if (!string.IsNullOrEmpty(translation)) + { + return translation; + } + } + } + } + return Application.productName; + } + + public static void LocalizeAll(bool Force = false) + { + LoadCurrentLanguage(); + if (!Application.isPlaying) + { + DoLocalizeAll(Force); + return; + } + mLocalizeIsScheduledWithForcedValue |= Force; + if (!mLocalizeIsScheduled) + { + CoroutineManager.Start(Coroutine_LocalizeAll()); + } + } + + private static IEnumerator Coroutine_LocalizeAll() + { + mLocalizeIsScheduled = true; + yield return null; + mLocalizeIsScheduled = false; + bool force = mLocalizeIsScheduledWithForcedValue; + mLocalizeIsScheduledWithForcedValue = false; + DoLocalizeAll(force); + } + + private static void DoLocalizeAll(bool Force = false) + { + Localize[] array = (Localize[])Resources.FindObjectsOfTypeAll(typeof(Localize)); + int i = 0; + for (int num = array.Length; i < num; i++) + { + array[i].OnLocalize(Force); + } + if (LocalizationManager.OnLocalizeEvent != null) + { + LocalizationManager.OnLocalizeEvent(); + } + } + + public static List<string> GetCategories() + { + List<string> list = new List<string>(); + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + Sources[i].GetCategories(OnlyMainCategory: false, list); + } + return list; + } + + public static List<string> GetTermsList(string Category = null) + { + if (Sources.Count == 0) + { + UpdateSources(); + } + if (Sources.Count == 1) + { + return Sources[0].GetTermsList(Category); + } + HashSet<string> hashSet = new HashSet<string>(); + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + hashSet.UnionWith(Sources[i].GetTermsList(Category)); + } + return new List<string>(hashSet); + } + + public static TermData GetTermData(string term) + { + InitializeIfNeeded(); + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + TermData termData = Sources[i].GetTermData(term); + if (termData != null) + { + return termData; + } + } + return null; + } + + public static TermData GetTermData(string term, out LanguageSourceData source) + { + InitializeIfNeeded(); + int i = 0; + for (int count = Sources.Count; i < count; i++) + { + TermData termData = Sources[i].GetTermData(term); + if (termData != null) + { + source = Sources[i]; + return termData; + } + } + source = null; + return null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationParamsManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationParamsManager.cs new file mode 100644 index 0000000..2690bf1 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationParamsManager.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace I2.Loc; + +public class LocalizationParamsManager : MonoBehaviour, ILocalizationParamsManager +{ + [Serializable] + public struct ParamValue + { + public string Name; + + public string Value; + } + + [SerializeField] + public List<ParamValue> _Params = new List<ParamValue>(); + + public bool _IsGlobalManager; + + public string GetParameterValue(string ParamName) + { + if (_Params != null) + { + int i = 0; + for (int count = _Params.Count; i < count; i++) + { + if (_Params[i].Name == ParamName) + { + return _Params[i].Value; + } + } + } + return null; + } + + public void SetParameterValue(string ParamName, string ParamValue, bool localize = true) + { + bool flag = false; + int i = 0; + for (int count = _Params.Count; i < count; i++) + { + if (_Params[i].Name == ParamName) + { + ParamValue value = _Params[i]; + value.Value = ParamValue; + _Params[i] = value; + flag = true; + break; + } + } + if (!flag) + { + _Params.Add(new ParamValue + { + Name = ParamName, + Value = ParamValue + }); + } + if (localize) + { + OnLocalize(); + } + } + + public void OnLocalize() + { + Localize component = GetComponent<Localize>(); + if (component != null) + { + component.OnLocalize(Force: true); + } + } + + public virtual void OnEnable() + { + if (_IsGlobalManager) + { + DoAutoRegister(); + } + } + + public void DoAutoRegister() + { + if (!LocalizationManager.ParamManagers.Contains(this)) + { + LocalizationManager.ParamManagers.Add(this); + LocalizationManager.LocalizeAll(Force: true); + } + } + + public void OnDisable() + { + LocalizationManager.ParamManagers.Remove(this); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationReader.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationReader.cs new file mode 100644 index 0000000..a940e76 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizationReader.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEngine; + +namespace I2.Loc; + +public class LocalizationReader +{ + public static Dictionary<string, string> ReadTextAsset(TextAsset asset) + { + StringReader stringReader = new StringReader(Encoding.UTF8.GetString(asset.bytes, 0, asset.bytes.Length).Replace("\r\n", "\n").Replace("\r", "\n")); + Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); + string line; + while ((line = stringReader.ReadLine()) != null) + { + if (TextAsset_ReadLine(line, out var key, out var value, out var _, out var _, out var _) && !string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value)) + { + dictionary[key] = value; + } + } + return dictionary; + } + + public static bool TextAsset_ReadLine(string line, out string key, out string value, out string category, out string comment, out string termType) + { + key = string.Empty; + category = string.Empty; + comment = string.Empty; + termType = string.Empty; + value = string.Empty; + int num = line.LastIndexOf("//", StringComparison.Ordinal); + if (num >= 0) + { + comment = line.Substring(num + 2).Trim(); + comment = DecodeString(comment); + line = line.Substring(0, num); + } + int num2 = line.IndexOf("=", StringComparison.Ordinal); + if (num2 < 0) + { + return false; + } + key = line.Substring(0, num2).Trim(); + value = line.Substring(num2 + 1).Trim(); + value = value.Replace("\r\n", "\n").Replace("\n", "\\n"); + value = DecodeString(value); + if (key.Length > 2 && key[0] == '[') + { + int num3 = key.IndexOf(']'); + if (num3 >= 0) + { + termType = key.Substring(1, num3 - 1); + key = key.Substring(num3 + 1); + } + } + ValidateFullTerm(ref key); + return true; + } + + public static string ReadCSVfile(string Path, Encoding encoding) + { + string text = string.Empty; + using (StreamReader streamReader = new StreamReader(Path, encoding)) + { + text = streamReader.ReadToEnd(); + } + text = text.Replace("\r\n", "\n"); + return text.Replace("\r", "\n"); + } + + public static List<string[]> ReadCSV(string Text, char Separator = ',') + { + int iStart = 0; + List<string[]> list = new List<string[]>(); + while (iStart < Text.Length) + { + string[] array = ParseCSVline(Text, ref iStart, Separator); + if (array == null) + { + break; + } + list.Add(array); + } + return list; + } + + private static string[] ParseCSVline(string Line, ref int iStart, char Separator) + { + List<string> list = new List<string>(); + int length = Line.Length; + int iWordStart = iStart; + bool flag = false; + while (iStart < length) + { + char c = Line[iStart]; + if (flag) + { + if (c == '"') + { + if (iStart + 1 >= length || Line[iStart + 1] != '"') + { + flag = false; + } + else if (iStart + 2 < length && Line[iStart + 2] == '"') + { + flag = false; + iStart += 2; + } + else + { + iStart++; + } + } + } + else if (c == '\n' || c == Separator) + { + AddCSVtoken(ref list, ref Line, iStart, ref iWordStart); + if (c == '\n') + { + iStart++; + break; + } + } + else if (c == '"') + { + flag = true; + } + iStart++; + } + if (iStart > iWordStart) + { + AddCSVtoken(ref list, ref Line, iStart, ref iWordStart); + } + return list.ToArray(); + } + + private static void AddCSVtoken(ref List<string> list, ref string Line, int iEnd, ref int iWordStart) + { + string text = Line.Substring(iWordStart, iEnd - iWordStart); + iWordStart = iEnd + 1; + text = text.Replace("\"\"", "\""); + if (text.Length > 1 && text[0] == '"' && text[text.Length - 1] == '"') + { + text = text.Substring(1, text.Length - 2); + } + list.Add(text); + } + + public static List<string[]> ReadI2CSV(string Text) + { + string[] separator = new string[1] { "[*]" }; + string[] separator2 = new string[1] { "[ln]" }; + List<string[]> list = new List<string[]>(); + string[] array = Text.Split(separator2, StringSplitOptions.None); + foreach (string text in array) + { + list.Add(text.Split(separator, StringSplitOptions.None)); + } + return list; + } + + public static void ValidateFullTerm(ref string Term) + { + Term = Term.Replace('\\', '/'); + int num = Term.IndexOf('/'); + if (num >= 0) + { + int startIndex; + while ((startIndex = Term.LastIndexOf('/')) != num) + { + Term = Term.Remove(startIndex, 1); + } + } + } + + public static string EncodeString(string str) + { + if (string.IsNullOrEmpty(str)) + { + return string.Empty; + } + return str.Replace("\r\n", "<\\n>").Replace("\r", "<\\n>").Replace("\n", "<\\n>"); + } + + public static string DecodeString(string str) + { + if (string.IsNullOrEmpty(str)) + { + return string.Empty; + } + return str.Replace("<\\n>", "\r\n"); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/Localize.cs b/Thronefall_v1.57/Thronefall/I2.Loc/Localize.cs new file mode 100644 index 0000000..5fc8fac --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/Localize.cs @@ -0,0 +1,464 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.Events; + +namespace I2.Loc; + +[AddComponentMenu("I2/Localization/I2 Localize")] +public class Localize : MonoBehaviour +{ + public enum TermModification + { + DontModify, + ToUpper, + ToLower, + ToUpperFirst, + ToTitle + } + + public string mTerm = string.Empty; + + public string mTermSecondary = string.Empty; + + [NonSerialized] + public string FinalTerm; + + [NonSerialized] + public string FinalSecondaryTerm; + + public TermModification PrimaryTermModifier; + + public TermModification SecondaryTermModifier; + + public string TermPrefix; + + public string TermSuffix; + + public bool LocalizeOnAwake = true; + + private string LastLocalizedLanguage; + + public bool IgnoreRTL; + + public int MaxCharactersInRTL; + + public bool IgnoreNumbersInRTL = true; + + public bool CorrectAlignmentForRTL = true; + + public bool AddSpacesToJoinedLanguages; + + public bool AllowLocalizedParameters = true; + + public bool AllowParameters = true; + + public List<UnityEngine.Object> TranslatedObjects = new List<UnityEngine.Object>(); + + [NonSerialized] + public Dictionary<string, UnityEngine.Object> mAssetDictionary = new Dictionary<string, UnityEngine.Object>(StringComparer.Ordinal); + + public UnityEvent LocalizeEvent = new UnityEvent(); + + public static string MainTranslation; + + public static string SecondaryTranslation; + + public static string CallBackTerm; + + public static string CallBackSecondaryTerm; + + public static Localize CurrentLocalizeComponent; + + public bool AlwaysForceLocalize; + + [SerializeField] + public EventCallback LocalizeCallBack = new EventCallback(); + + public bool mGUI_ShowReferences; + + public bool mGUI_ShowTems = true; + + public bool mGUI_ShowCallback; + + public ILocalizeTarget mLocalizeTarget; + + public string mLocalizeTargetName; + + public string Term + { + get + { + return mTerm; + } + set + { + SetTerm(value); + } + } + + public string SecondaryTerm + { + get + { + return mTermSecondary; + } + set + { + SetTerm(null, value); + } + } + + private void Awake() + { + UpdateAssetDictionary(); + FindTarget(); + if (LocalizeOnAwake) + { + OnLocalize(); + } + } + + private void OnEnable() + { + OnLocalize(); + } + + public bool HasCallback() + { + if (LocalizeCallBack.HasCallback()) + { + return true; + } + return LocalizeEvent.GetPersistentEventCount() > 0; + } + + public void OnLocalize(bool Force = false) + { + if ((!Force && (!base.enabled || base.gameObject == null || !base.gameObject.activeInHierarchy)) || string.IsNullOrEmpty(LocalizationManager.CurrentLanguage) || (!AlwaysForceLocalize && !Force && !HasCallback() && LastLocalizedLanguage == LocalizationManager.CurrentLanguage)) + { + return; + } + LastLocalizedLanguage = LocalizationManager.CurrentLanguage; + if (string.IsNullOrEmpty(FinalTerm) || string.IsNullOrEmpty(FinalSecondaryTerm)) + { + GetFinalTerms(out FinalTerm, out FinalSecondaryTerm); + } + bool flag = I2Utils.IsPlaying() && HasCallback(); + if (!flag && string.IsNullOrEmpty(FinalTerm) && string.IsNullOrEmpty(FinalSecondaryTerm)) + { + return; + } + CurrentLocalizeComponent = this; + CallBackTerm = FinalTerm; + CallBackSecondaryTerm = FinalSecondaryTerm; + MainTranslation = ((string.IsNullOrEmpty(FinalTerm) || FinalTerm == "-") ? null : LocalizationManager.GetTranslation(FinalTerm, FixForRTL: false)); + SecondaryTranslation = ((string.IsNullOrEmpty(FinalSecondaryTerm) || FinalSecondaryTerm == "-") ? null : LocalizationManager.GetTranslation(FinalSecondaryTerm, FixForRTL: false)); + if (!flag && string.IsNullOrEmpty(FinalTerm) && string.IsNullOrEmpty(SecondaryTranslation)) + { + return; + } + LocalizeCallBack.Execute(this); + LocalizeEvent.Invoke(); + if (AllowParameters) + { + LocalizationManager.ApplyLocalizationParams(ref MainTranslation, base.gameObject, AllowLocalizedParameters); + } + if (!FindTarget()) + { + return; + } + bool flag2 = LocalizationManager.IsRight2Left && !IgnoreRTL; + if (MainTranslation != null) + { + switch (PrimaryTermModifier) + { + case TermModification.ToUpper: + MainTranslation = MainTranslation.ToUpper(); + break; + case TermModification.ToLower: + MainTranslation = MainTranslation.ToLower(); + break; + case TermModification.ToUpperFirst: + MainTranslation = GoogleTranslation.UppercaseFirst(MainTranslation); + break; + case TermModification.ToTitle: + MainTranslation = GoogleTranslation.TitleCase(MainTranslation); + break; + } + if (!string.IsNullOrEmpty(TermPrefix)) + { + MainTranslation = (flag2 ? (MainTranslation + TermPrefix) : (TermPrefix + MainTranslation)); + } + if (!string.IsNullOrEmpty(TermSuffix)) + { + MainTranslation = (flag2 ? (TermSuffix + MainTranslation) : (MainTranslation + TermSuffix)); + } + if (AddSpacesToJoinedLanguages && LocalizationManager.HasJoinedWords && !string.IsNullOrEmpty(MainTranslation)) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append(MainTranslation[0]); + int i = 1; + for (int length = MainTranslation.Length; i < length; i++) + { + stringBuilder.Append(' '); + stringBuilder.Append(MainTranslation[i]); + } + MainTranslation = stringBuilder.ToString(); + } + if (flag2 && mLocalizeTarget.AllowMainTermToBeRTL() && !string.IsNullOrEmpty(MainTranslation)) + { + MainTranslation = LocalizationManager.ApplyRTLfix(MainTranslation, MaxCharactersInRTL, IgnoreNumbersInRTL); + } + } + if (SecondaryTranslation != null) + { + switch (SecondaryTermModifier) + { + case TermModification.ToUpper: + SecondaryTranslation = SecondaryTranslation.ToUpper(); + break; + case TermModification.ToLower: + SecondaryTranslation = SecondaryTranslation.ToLower(); + break; + case TermModification.ToUpperFirst: + SecondaryTranslation = GoogleTranslation.UppercaseFirst(SecondaryTranslation); + break; + case TermModification.ToTitle: + SecondaryTranslation = GoogleTranslation.TitleCase(SecondaryTranslation); + break; + } + if (flag2 && mLocalizeTarget.AllowSecondTermToBeRTL() && !string.IsNullOrEmpty(SecondaryTranslation)) + { + SecondaryTranslation = LocalizationManager.ApplyRTLfix(SecondaryTranslation); + } + } + if (LocalizationManager.HighlightLocalizedTargets) + { + MainTranslation = "LOC:" + FinalTerm; + } + mLocalizeTarget.DoLocalize(this, MainTranslation, SecondaryTranslation); + CurrentLocalizeComponent = null; + } + + public bool FindTarget() + { + if (mLocalizeTarget != null && mLocalizeTarget.IsValid(this)) + { + return true; + } + if (mLocalizeTarget != null) + { + UnityEngine.Object.DestroyImmediate(mLocalizeTarget); + mLocalizeTarget = null; + mLocalizeTargetName = null; + } + if (!string.IsNullOrEmpty(mLocalizeTargetName)) + { + foreach (ILocalizeTargetDescriptor mLocalizeTarget in LocalizationManager.mLocalizeTargets) + { + if (mLocalizeTargetName == mLocalizeTarget.GetTargetType().ToString()) + { + if (mLocalizeTarget.CanLocalize(this)) + { + this.mLocalizeTarget = mLocalizeTarget.CreateTarget(this); + } + if (this.mLocalizeTarget != null) + { + return true; + } + } + } + } + foreach (ILocalizeTargetDescriptor mLocalizeTarget2 in LocalizationManager.mLocalizeTargets) + { + if (mLocalizeTarget2.CanLocalize(this)) + { + this.mLocalizeTarget = mLocalizeTarget2.CreateTarget(this); + mLocalizeTargetName = mLocalizeTarget2.GetTargetType().ToString(); + if (this.mLocalizeTarget != null) + { + return true; + } + } + } + return false; + } + + public void GetFinalTerms(out string primaryTerm, out string secondaryTerm) + { + primaryTerm = string.Empty; + secondaryTerm = string.Empty; + if (FindTarget()) + { + if (mLocalizeTarget != null) + { + mLocalizeTarget.GetFinalTerms(this, mTerm, mTermSecondary, out primaryTerm, out secondaryTerm); + primaryTerm = I2Utils.GetValidTermName(primaryTerm); + } + if (!string.IsNullOrEmpty(mTerm)) + { + primaryTerm = mTerm; + } + if (!string.IsNullOrEmpty(mTermSecondary)) + { + secondaryTerm = mTermSecondary; + } + if (primaryTerm != null) + { + primaryTerm = primaryTerm.Trim(); + } + if (secondaryTerm != null) + { + secondaryTerm = secondaryTerm.Trim(); + } + } + } + + public string GetMainTargetsText() + { + string primaryTerm = null; + string secondaryTerm = null; + if (mLocalizeTarget != null) + { + mLocalizeTarget.GetFinalTerms(this, null, null, out primaryTerm, out secondaryTerm); + } + if (!string.IsNullOrEmpty(primaryTerm)) + { + return primaryTerm; + } + return mTerm; + } + + public void SetFinalTerms(string Main, string Secondary, out string primaryTerm, out string secondaryTerm, bool RemoveNonASCII) + { + primaryTerm = (RemoveNonASCII ? I2Utils.GetValidTermName(Main) : Main); + secondaryTerm = Secondary; + } + + public void SetTerm(string primary) + { + if (!string.IsNullOrEmpty(primary)) + { + FinalTerm = (mTerm = primary); + } + OnLocalize(Force: true); + } + + public void SetTerm(string primary, string secondary) + { + if (!string.IsNullOrEmpty(primary)) + { + FinalTerm = (mTerm = primary); + } + FinalSecondaryTerm = (mTermSecondary = secondary); + OnLocalize(Force: true); + } + + internal T GetSecondaryTranslatedObj<T>(ref string mainTranslation, ref string secondaryTranslation) where T : UnityEngine.Object + { + DeserializeTranslation(mainTranslation, out var value, out var secondary); + T val = null; + if (!string.IsNullOrEmpty(secondary)) + { + val = GetObject<T>(secondary); + if ((UnityEngine.Object)val != (UnityEngine.Object)null) + { + mainTranslation = value; + secondaryTranslation = secondary; + } + } + if ((UnityEngine.Object)val == (UnityEngine.Object)null) + { + val = GetObject<T>(secondaryTranslation); + } + return val; + } + + public void UpdateAssetDictionary() + { + TranslatedObjects.RemoveAll((UnityEngine.Object x) => x == null); + mAssetDictionary = (from o in TranslatedObjects.Distinct() + group o by o.name).ToDictionary((IGrouping<string, UnityEngine.Object> g) => g.Key, (IGrouping<string, UnityEngine.Object> g) => g.First()); + } + + internal T GetObject<T>(string Translation) where T : UnityEngine.Object + { + if (string.IsNullOrEmpty(Translation)) + { + return null; + } + return GetTranslatedObject<T>(Translation); + } + + private T GetTranslatedObject<T>(string Translation) where T : UnityEngine.Object + { + return FindTranslatedObject<T>(Translation); + } + + private void DeserializeTranslation(string translation, out string value, out string secondary) + { + if (!string.IsNullOrEmpty(translation) && translation.Length > 1 && translation[0] == '[') + { + int num = translation.IndexOf(']'); + if (num > 0) + { + secondary = translation.Substring(1, num - 1); + value = translation.Substring(num + 1); + return; + } + } + value = translation; + secondary = string.Empty; + } + + public T FindTranslatedObject<T>(string value) where T : UnityEngine.Object + { + if (string.IsNullOrEmpty(value)) + { + return null; + } + if (mAssetDictionary == null || mAssetDictionary.Count != TranslatedObjects.Count) + { + UpdateAssetDictionary(); + } + foreach (KeyValuePair<string, UnityEngine.Object> item in mAssetDictionary) + { + if (item.Value is T && value.EndsWith(item.Key, StringComparison.OrdinalIgnoreCase) && string.Compare(value, item.Key, StringComparison.OrdinalIgnoreCase) == 0) + { + return (T)item.Value; + } + } + T val = LocalizationManager.FindAsset(value) as T; + if ((bool)(UnityEngine.Object)val) + { + return val; + } + return ResourceManager.pInstance.GetAsset<T>(value); + } + + public bool HasTranslatedObject(UnityEngine.Object Obj) + { + if (TranslatedObjects.Contains(Obj)) + { + return true; + } + return ResourceManager.pInstance.HasAsset(Obj); + } + + public void AddTranslatedObject(UnityEngine.Object Obj) + { + if (!TranslatedObjects.Contains(Obj)) + { + TranslatedObjects.Add(Obj); + UpdateAssetDictionary(); + } + } + + public void SetGlobalLanguage(string Language) + { + LocalizationManager.CurrentLanguage = Language; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeDropdown.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeDropdown.cs new file mode 100644 index 0000000..57fd328 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeDropdown.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +namespace I2.Loc; + +[AddComponentMenu("I2/Localization/Localize Dropdown")] +public class LocalizeDropdown : MonoBehaviour +{ + public List<string> _Terms = new List<string>(); + + public void Start() + { + LocalizationManager.OnLocalizeEvent += OnLocalize; + OnLocalize(); + } + + public void OnDestroy() + { + LocalizationManager.OnLocalizeEvent -= OnLocalize; + } + + private void OnEnable() + { + if (_Terms.Count == 0) + { + FillValues(); + } + OnLocalize(); + } + + public void OnLocalize() + { + if (base.enabled && !(base.gameObject == null) && base.gameObject.activeInHierarchy && !string.IsNullOrEmpty(LocalizationManager.CurrentLanguage)) + { + UpdateLocalization(); + } + } + + private void FillValues() + { + Dropdown component = GetComponent<Dropdown>(); + if (component == null && I2Utils.IsPlaying()) + { + FillValuesTMPro(); + return; + } + foreach (Dropdown.OptionData option in component.options) + { + _Terms.Add(option.text); + } + } + + public void UpdateLocalization() + { + Dropdown component = GetComponent<Dropdown>(); + if (component == null) + { + UpdateLocalizationTMPro(); + return; + } + component.options.Clear(); + foreach (string term in _Terms) + { + string text = TextTranslator.Translate(term); + component.options.Add(new Dropdown.OptionData(text)); + } + component.RefreshShownValue(); + } + + public void UpdateLocalizationTMPro() + { + TMP_Dropdown component = GetComponent<TMP_Dropdown>(); + if (component == null) + { + return; + } + component.options.Clear(); + foreach (string term in _Terms) + { + string text = TextTranslator.Translate(term); + component.options.Add(new TMP_Dropdown.OptionData(text)); + } + component.RefreshShownValue(); + } + + private void FillValuesTMPro() + { + TMP_Dropdown component = GetComponent<TMP_Dropdown>(); + if (component == null) + { + return; + } + foreach (TMP_Dropdown.OptionData option in component.options) + { + _Terms.Add(option.text); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget.cs new file mode 100644 index 0000000..a746e60 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +namespace I2.Loc; + +public abstract class LocalizeTarget<T> : ILocalizeTarget where T : Object +{ + public T mTarget; + + public override bool IsValid(Localize cmp) + { + if ((Object)mTarget != (Object)null) + { + Component component = mTarget as Component; + if (component != null && component.gameObject != cmp.gameObject) + { + mTarget = null; + } + } + if ((Object)mTarget == (Object)null) + { + mTarget = cmp.GetComponent<T>(); + } + return (Object)mTarget != (Object)null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc.cs new file mode 100644 index 0000000..44f67b2 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc.cs @@ -0,0 +1,17 @@ +using System; +using UnityEngine; + +namespace I2.Loc; + +public abstract class LocalizeTargetDesc<T> : ILocalizeTargetDescriptor where T : ILocalizeTarget +{ + public override ILocalizeTarget CreateTarget(Localize cmp) + { + return ScriptableObject.CreateInstance<T>(); + } + + public override Type GetTargetType() + { + return typeof(T); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Child.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Child.cs new file mode 100644 index 0000000..e8401c7 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Child.cs @@ -0,0 +1,9 @@ +namespace I2.Loc; + +public class LocalizeTargetDesc_Child : LocalizeTargetDesc<LocalizeTarget_UnityStandard_Child> +{ + public override bool CanLocalize(Localize cmp) + { + return cmp.transform.childCount > 1; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Prefab.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Prefab.cs new file mode 100644 index 0000000..ee10200 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Prefab.cs @@ -0,0 +1,9 @@ +namespace I2.Loc; + +public class LocalizeTargetDesc_Prefab : LocalizeTargetDesc<LocalizeTarget_UnityStandard_Prefab> +{ + public override bool CanLocalize(Localize cmp) + { + return true; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Type.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Type.cs new file mode 100644 index 0000000..5ee9dba --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTargetDesc_Type.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTargetDesc_Type<T, G> : LocalizeTargetDesc<G> where T : Object where G : LocalizeTarget<T> +{ + public override bool CanLocalize(Localize cmp) + { + return (Object)cmp.GetComponent<T>() != (Object)null; + } + + public override ILocalizeTarget CreateTarget(Localize cmp) + { + T component = cmp.GetComponent<T>(); + if ((Object)component == (Object)null) + { + return null; + } + G val = ScriptableObject.CreateInstance<G>(); + val.mTarget = component; + return val; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_TextMeshPro_Label.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_TextMeshPro_Label.cs new file mode 100644 index 0000000..6802642 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_TextMeshPro_Label.cs @@ -0,0 +1,257 @@ +using System; +using TMPro; +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_TextMeshPro_Label : LocalizeTarget<TextMeshPro> +{ + private TextAlignmentOptions mAlignment_RTL = TextAlignmentOptions.Right; + + private TextAlignmentOptions mAlignment_LTR = TextAlignmentOptions.Left; + + private bool mAlignmentWasRTL; + + private bool mInitializeAlignment = true; + + static LocalizeTarget_TextMeshPro_Label() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<TextMeshPro, LocalizeTarget_TextMeshPro_Label> + { + Name = "TextMeshPro Label", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Font; + } + + public override bool CanUseSecondaryTerm() + { + return true; + } + + public override bool AllowMainTermToBeRTL() + { + return true; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = (mTarget ? mTarget.text : null); + secondaryTerm = ((mTarget.font != null) ? mTarget.font.name : string.Empty); + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + TMP_FontAsset secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<TMP_FontAsset>(ref mainTranslation, ref secondaryTranslation); + if (secondaryTranslatedObj != null) + { + SetFont(mTarget, secondaryTranslatedObj); + } + else + { + Material secondaryTranslatedObj2 = cmp.GetSecondaryTranslatedObj<Material>(ref mainTranslation, ref secondaryTranslation); + if (secondaryTranslatedObj2 != null && mTarget.fontMaterial != secondaryTranslatedObj2) + { + if (!secondaryTranslatedObj2.name.StartsWith(mTarget.font.name, StringComparison.Ordinal)) + { + secondaryTranslatedObj = GetTMPFontFromMaterial(cmp, secondaryTranslation.EndsWith(secondaryTranslatedObj2.name, StringComparison.Ordinal) ? secondaryTranslation : secondaryTranslatedObj2.name); + if (secondaryTranslatedObj != null) + { + SetFont(mTarget, secondaryTranslatedObj); + } + } + SetMaterial(mTarget, secondaryTranslatedObj2); + } + } + if (mInitializeAlignment) + { + mInitializeAlignment = false; + mAlignmentWasRTL = LocalizationManager.IsRight2Left; + InitAlignment_TMPro(mAlignmentWasRTL, mTarget.alignment, out mAlignment_LTR, out mAlignment_RTL); + } + else + { + InitAlignment_TMPro(mAlignmentWasRTL, mTarget.alignment, out var alignLTR, out var alignRTL); + if ((mAlignmentWasRTL && mAlignment_RTL != alignRTL) || (!mAlignmentWasRTL && mAlignment_LTR != alignLTR)) + { + mAlignment_LTR = alignLTR; + mAlignment_RTL = alignRTL; + } + mAlignmentWasRTL = LocalizationManager.IsRight2Left; + } + if (mainTranslation != null && mTarget.text != mainTranslation) + { + if (cmp.CorrectAlignmentForRTL) + { + mTarget.alignment = (LocalizationManager.IsRight2Left ? mAlignment_RTL : mAlignment_LTR); + } + mTarget.isRightToLeftText = LocalizationManager.IsRight2Left; + if (LocalizationManager.IsRight2Left) + { + mainTranslation = I2Utils.ReverseText(mainTranslation); + } + mTarget.text = mainTranslation; + } + } + + internal static TMP_FontAsset GetTMPFontFromMaterial(Localize cmp, string matName) + { + string text = " .\\/-[]()"; + int num = matName.Length - 1; + while (num > 0) + { + while (num > 0 && text.IndexOf(matName[num]) >= 0) + { + num--; + } + if (num <= 0) + { + break; + } + string translation = matName.Substring(0, num + 1); + TMP_FontAsset @object = cmp.GetObject<TMP_FontAsset>(translation); + if (@object != null) + { + return @object; + } + while (num > 0 && text.IndexOf(matName[num]) < 0) + { + num--; + } + } + return null; + } + + internal static void InitAlignment_TMPro(bool isRTL, TextAlignmentOptions alignment, out TextAlignmentOptions alignLTR, out TextAlignmentOptions alignRTL) + { + alignLTR = (alignRTL = alignment); + if (isRTL) + { + switch (alignment) + { + case TextAlignmentOptions.TopRight: + alignLTR = TextAlignmentOptions.TopLeft; + break; + case TextAlignmentOptions.Right: + alignLTR = TextAlignmentOptions.Left; + break; + case TextAlignmentOptions.BottomRight: + alignLTR = TextAlignmentOptions.BottomLeft; + break; + case TextAlignmentOptions.BaselineRight: + alignLTR = TextAlignmentOptions.BaselineLeft; + break; + case TextAlignmentOptions.MidlineRight: + alignLTR = TextAlignmentOptions.MidlineLeft; + break; + case TextAlignmentOptions.CaplineRight: + alignLTR = TextAlignmentOptions.CaplineLeft; + break; + case TextAlignmentOptions.TopLeft: + alignLTR = TextAlignmentOptions.TopRight; + break; + case TextAlignmentOptions.Left: + alignLTR = TextAlignmentOptions.Right; + break; + case TextAlignmentOptions.BottomLeft: + alignLTR = TextAlignmentOptions.BottomRight; + break; + case TextAlignmentOptions.BaselineLeft: + alignLTR = TextAlignmentOptions.BaselineRight; + break; + case TextAlignmentOptions.MidlineLeft: + alignLTR = TextAlignmentOptions.MidlineRight; + break; + case TextAlignmentOptions.CaplineLeft: + alignLTR = TextAlignmentOptions.CaplineRight; + break; + } + } + else + { + switch (alignment) + { + case TextAlignmentOptions.TopRight: + alignRTL = TextAlignmentOptions.TopLeft; + break; + case TextAlignmentOptions.Right: + alignRTL = TextAlignmentOptions.Left; + break; + case TextAlignmentOptions.BottomRight: + alignRTL = TextAlignmentOptions.BottomLeft; + break; + case TextAlignmentOptions.BaselineRight: + alignRTL = TextAlignmentOptions.BaselineLeft; + break; + case TextAlignmentOptions.MidlineRight: + alignRTL = TextAlignmentOptions.MidlineLeft; + break; + case TextAlignmentOptions.CaplineRight: + alignRTL = TextAlignmentOptions.CaplineLeft; + break; + case TextAlignmentOptions.TopLeft: + alignRTL = TextAlignmentOptions.TopRight; + break; + case TextAlignmentOptions.Left: + alignRTL = TextAlignmentOptions.Right; + break; + case TextAlignmentOptions.BottomLeft: + alignRTL = TextAlignmentOptions.BottomRight; + break; + case TextAlignmentOptions.BaselineLeft: + alignRTL = TextAlignmentOptions.BaselineRight; + break; + case TextAlignmentOptions.MidlineLeft: + alignRTL = TextAlignmentOptions.MidlineRight; + break; + case TextAlignmentOptions.CaplineLeft: + alignRTL = TextAlignmentOptions.CaplineRight; + break; + } + } + } + + internal static void SetFont(TMP_Text label, TMP_FontAsset newFont) + { + if (label.font != newFont) + { + label.font = newFont; + } + if (label.linkedTextComponent != null) + { + SetFont(label.linkedTextComponent, newFont); + } + } + + internal static void SetMaterial(TMP_Text label, Material newMat) + { + if (label.fontSharedMaterial != newMat) + { + label.fontSharedMaterial = newMat; + } + if (label.linkedTextComponent != null) + { + SetMaterial(label.linkedTextComponent, newMat); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_TextMeshPro_UGUI.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_TextMeshPro_UGUI.cs new file mode 100644 index 0000000..e2f3d7d --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_TextMeshPro_UGUI.cs @@ -0,0 +1,116 @@ +using System; +using TMPro; +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_TextMeshPro_UGUI : LocalizeTarget<TextMeshProUGUI> +{ + public TextAlignmentOptions mAlignment_RTL = TextAlignmentOptions.Right; + + public TextAlignmentOptions mAlignment_LTR = TextAlignmentOptions.Left; + + public bool mAlignmentWasRTL; + + public bool mInitializeAlignment = true; + + static LocalizeTarget_TextMeshPro_UGUI() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<TextMeshProUGUI, LocalizeTarget_TextMeshPro_UGUI> + { + Name = "TextMeshPro UGUI", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.TextMeshPFont; + } + + public override bool CanUseSecondaryTerm() + { + return true; + } + + public override bool AllowMainTermToBeRTL() + { + return true; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = (mTarget ? mTarget.text : null); + secondaryTerm = ((mTarget.font != null) ? mTarget.font.name : string.Empty); + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + TMP_FontAsset secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<TMP_FontAsset>(ref mainTranslation, ref secondaryTranslation); + if (secondaryTranslatedObj != null) + { + LocalizeTarget_TextMeshPro_Label.SetFont(mTarget, secondaryTranslatedObj); + } + else + { + Material secondaryTranslatedObj2 = cmp.GetSecondaryTranslatedObj<Material>(ref mainTranslation, ref secondaryTranslation); + if (secondaryTranslatedObj2 != null && mTarget.fontMaterial != secondaryTranslatedObj2) + { + if (!secondaryTranslatedObj2.name.StartsWith(mTarget.font.name, StringComparison.Ordinal)) + { + secondaryTranslatedObj = LocalizeTarget_TextMeshPro_Label.GetTMPFontFromMaterial(cmp, secondaryTranslation.EndsWith(secondaryTranslatedObj2.name, StringComparison.Ordinal) ? secondaryTranslation : secondaryTranslatedObj2.name); + if (secondaryTranslatedObj != null) + { + LocalizeTarget_TextMeshPro_Label.SetFont(mTarget, secondaryTranslatedObj); + } + } + LocalizeTarget_TextMeshPro_Label.SetMaterial(mTarget, secondaryTranslatedObj2); + } + } + if (mInitializeAlignment) + { + mInitializeAlignment = false; + mAlignmentWasRTL = LocalizationManager.IsRight2Left; + LocalizeTarget_TextMeshPro_Label.InitAlignment_TMPro(mAlignmentWasRTL, mTarget.alignment, out mAlignment_LTR, out mAlignment_RTL); + } + else + { + LocalizeTarget_TextMeshPro_Label.InitAlignment_TMPro(mAlignmentWasRTL, mTarget.alignment, out var alignLTR, out var alignRTL); + if ((mAlignmentWasRTL && mAlignment_RTL != alignRTL) || (!mAlignmentWasRTL && mAlignment_LTR != alignLTR)) + { + mAlignment_LTR = alignLTR; + mAlignment_RTL = alignRTL; + } + mAlignmentWasRTL = LocalizationManager.IsRight2Left; + } + if (mainTranslation != null && mTarget.text != mainTranslation) + { + if (cmp.CorrectAlignmentForRTL) + { + mTarget.alignment = (LocalizationManager.IsRight2Left ? mAlignment_RTL : mAlignment_LTR); + } + mTarget.isRightToLeftText = LocalizationManager.IsRight2Left; + if (LocalizationManager.IsRight2Left) + { + mainTranslation = I2Utils.ReverseText(mainTranslation); + } + mTarget.text = mainTranslation; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_AudioSource.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_AudioSource.cs new file mode 100644 index 0000000..b540830 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_AudioSource.cs @@ -0,0 +1,68 @@ +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_UnityStandard_AudioSource : LocalizeTarget<AudioSource> +{ + static LocalizeTarget_UnityStandard_AudioSource() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<AudioSource, LocalizeTarget_UnityStandard_AudioSource> + { + Name = "AudioSource", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.AudioClip; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override bool CanUseSecondaryTerm() + { + return false; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + AudioClip clip = mTarget.clip; + primaryTerm = (clip ? clip.name : string.Empty); + secondaryTerm = null; + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + bool num = (mTarget.isPlaying || mTarget.loop) && Application.isPlaying; + AudioClip clip = mTarget.clip; + AudioClip audioClip = cmp.FindTranslatedObject<AudioClip>(mainTranslation); + if (clip != audioClip) + { + mTarget.clip = audioClip; + } + if (num && (bool)mTarget.clip) + { + mTarget.Play(); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_Child.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_Child.cs new file mode 100644 index 0000000..da89189 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_Child.cs @@ -0,0 +1,76 @@ +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_UnityStandard_Child : LocalizeTarget<GameObject> +{ + static LocalizeTarget_UnityStandard_Child() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Child + { + Name = "Child", + Priority = 200 + }); + } + + public override bool IsValid(Localize cmp) + { + return cmp.transform.childCount > 1; + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.GameObject; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override bool CanUseSecondaryTerm() + { + return false; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = cmp.name; + secondaryTerm = null; + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + if (!string.IsNullOrEmpty(mainTranslation)) + { + Transform transform = cmp.transform; + string text = mainTranslation; + int num = mainTranslation.LastIndexOfAny(LanguageSourceData.CategorySeparators); + if (num >= 0) + { + text = text.Substring(num + 1); + } + for (int i = 0; i < transform.childCount; i++) + { + Transform child = transform.GetChild(i); + child.gameObject.SetActive(child.name == text); + } + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_MeshRenderer.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_MeshRenderer.cs new file mode 100644 index 0000000..07cbecd --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_MeshRenderer.cs @@ -0,0 +1,89 @@ +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_UnityStandard_MeshRenderer : LocalizeTarget<MeshRenderer> +{ + static LocalizeTarget_UnityStandard_MeshRenderer() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<MeshRenderer, LocalizeTarget_UnityStandard_MeshRenderer> + { + Name = "MeshRenderer", + Priority = 800 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Mesh; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Material; + } + + public override bool CanUseSecondaryTerm() + { + return true; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + if (mTarget == null) + { + primaryTerm = (secondaryTerm = null); + } + else + { + MeshFilter component = mTarget.GetComponent<MeshFilter>(); + if (component == null || component.sharedMesh == null) + { + primaryTerm = null; + } + else + { + primaryTerm = component.sharedMesh.name; + } + } + if (mTarget == null || mTarget.sharedMaterial == null) + { + secondaryTerm = null; + } + else + { + secondaryTerm = mTarget.sharedMaterial.name; + } + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + Material secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<Material>(ref mainTranslation, ref secondaryTranslation); + if (secondaryTranslatedObj != null && mTarget.sharedMaterial != secondaryTranslatedObj) + { + mTarget.material = secondaryTranslatedObj; + } + Mesh mesh = cmp.FindTranslatedObject<Mesh>(mainTranslation); + MeshFilter component = mTarget.GetComponent<MeshFilter>(); + if (mesh != null && component.sharedMesh != mesh) + { + component.mesh = mesh; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_Prefab.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_Prefab.cs new file mode 100644 index 0000000..a4c9d7e --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_Prefab.cs @@ -0,0 +1,108 @@ +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_UnityStandard_Prefab : LocalizeTarget<GameObject> +{ + static LocalizeTarget_UnityStandard_Prefab() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Prefab + { + Name = "Prefab", + Priority = 250 + }); + } + + public override bool IsValid(Localize cmp) + { + return true; + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.GameObject; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override bool CanUseSecondaryTerm() + { + return false; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = cmp.name; + secondaryTerm = null; + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + if (string.IsNullOrEmpty(mainTranslation) || ((bool)mTarget && mTarget.name == mainTranslation)) + { + return; + } + Transform transform = cmp.transform; + string text = mainTranslation; + int num = mainTranslation.LastIndexOfAny(LanguageSourceData.CategorySeparators); + if (num >= 0) + { + text = text.Substring(num + 1); + } + Transform transform2 = InstantiateNewPrefab(cmp, mainTranslation); + if (transform2 == null) + { + return; + } + transform2.name = text; + for (int num2 = transform.childCount - 1; num2 >= 0; num2--) + { + Transform child = transform.GetChild(num2); + if (child != transform2) + { + Object.Destroy(child.gameObject); + } + } + } + + private Transform InstantiateNewPrefab(Localize cmp, string mainTranslation) + { + GameObject gameObject = cmp.FindTranslatedObject<GameObject>(mainTranslation); + if (gameObject == null) + { + return null; + } + GameObject gameObject2 = mTarget; + mTarget = Object.Instantiate(gameObject); + if (mTarget == null) + { + return null; + } + Transform transform = cmp.transform; + Transform transform2 = mTarget.transform; + transform2.SetParent(transform); + Transform transform3 = (gameObject2 ? gameObject2.transform : transform); + transform2.rotation = transform3.rotation; + transform2.position = transform3.position; + return transform2; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_SpriteRenderer.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_SpriteRenderer.cs new file mode 100644 index 0000000..3acb521 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_SpriteRenderer.cs @@ -0,0 +1,62 @@ +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_UnityStandard_SpriteRenderer : LocalizeTarget<SpriteRenderer> +{ + static LocalizeTarget_UnityStandard_SpriteRenderer() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<SpriteRenderer, LocalizeTarget_UnityStandard_SpriteRenderer> + { + Name = "SpriteRenderer", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Sprite; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override bool CanUseSecondaryTerm() + { + return false; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + Sprite sprite = mTarget.sprite; + primaryTerm = ((sprite != null) ? sprite.name : string.Empty); + secondaryTerm = null; + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + Sprite sprite = mTarget.sprite; + if (sprite == null || sprite.name != mainTranslation) + { + mTarget.sprite = cmp.FindTranslatedObject<Sprite>(mainTranslation); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_TextMesh.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_TextMesh.cs new file mode 100644 index 0000000..4f3e629 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_TextMesh.cs @@ -0,0 +1,92 @@ +using UnityEngine; + +namespace I2.Loc; + +public class LocalizeTarget_UnityStandard_TextMesh : LocalizeTarget<TextMesh> +{ + private TextAlignment mAlignment_RTL = TextAlignment.Right; + + private TextAlignment mAlignment_LTR; + + private bool mAlignmentWasRTL; + + private bool mInitializeAlignment = true; + + static LocalizeTarget_UnityStandard_TextMesh() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<TextMesh, LocalizeTarget_UnityStandard_TextMesh> + { + Name = "TextMesh", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Font; + } + + public override bool CanUseSecondaryTerm() + { + return true; + } + + public override bool AllowMainTermToBeRTL() + { + return true; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = (mTarget ? mTarget.text : null); + secondaryTerm = ((string.IsNullOrEmpty(Secondary) && mTarget.font != null) ? mTarget.font.name : null); + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + Font secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<Font>(ref mainTranslation, ref secondaryTranslation); + if (secondaryTranslatedObj != null && mTarget.font != secondaryTranslatedObj) + { + mTarget.font = secondaryTranslatedObj; + mTarget.GetComponentInChildren<MeshRenderer>().material = secondaryTranslatedObj.material; + } + if (mInitializeAlignment) + { + mInitializeAlignment = false; + mAlignment_LTR = (mAlignment_RTL = mTarget.alignment); + if (LocalizationManager.IsRight2Left && mAlignment_RTL == TextAlignment.Right) + { + mAlignment_LTR = TextAlignment.Left; + } + if (!LocalizationManager.IsRight2Left && mAlignment_LTR == TextAlignment.Left) + { + mAlignment_RTL = TextAlignment.Right; + } + } + if (mainTranslation != null && mTarget.text != mainTranslation) + { + if (cmp.CorrectAlignmentForRTL && mTarget.alignment != TextAlignment.Center) + { + mTarget.alignment = (LocalizationManager.IsRight2Left ? mAlignment_RTL : mAlignment_LTR); + } + mTarget.font.RequestCharactersInTexture(mainTranslation); + mTarget.text = mainTranslation; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_VideoPlayer.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_VideoPlayer.cs new file mode 100644 index 0000000..fb2b0a0 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityStandard_VideoPlayer.cs @@ -0,0 +1,63 @@ +using UnityEngine; +using UnityEngine.Video; + +namespace I2.Loc; + +public class LocalizeTarget_UnityStandard_VideoPlayer : LocalizeTarget<VideoPlayer> +{ + static LocalizeTarget_UnityStandard_VideoPlayer() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<VideoPlayer, LocalizeTarget_UnityStandard_VideoPlayer> + { + Name = "VideoPlayer", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Video; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override bool CanUseSecondaryTerm() + { + return false; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + VideoClip clip = mTarget.clip; + primaryTerm = ((clip != null) ? clip.name : string.Empty); + secondaryTerm = null; + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + VideoClip clip = mTarget.clip; + if (clip == null || clip.name != mainTranslation) + { + mTarget.clip = cmp.FindTranslatedObject<VideoClip>(mainTranslation); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_Image.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_Image.cs new file mode 100644 index 0000000..4270743 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_Image.cs @@ -0,0 +1,70 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace I2.Loc; + +public class LocalizeTarget_UnityUI_Image : LocalizeTarget<Image> +{ + static LocalizeTarget_UnityUI_Image() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<Image, LocalizeTarget_UnityUI_Image> + { + Name = "Image", + Priority = 100 + }); + } + + public override bool CanUseSecondaryTerm() + { + return false; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + if (!(mTarget.sprite == null)) + { + return eTermType.Sprite; + } + return eTermType.Texture; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = (mTarget.mainTexture ? mTarget.mainTexture.name : ""); + if (mTarget.sprite != null && mTarget.sprite.name != primaryTerm) + { + primaryTerm = primaryTerm + "." + mTarget.sprite.name; + } + secondaryTerm = null; + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + Sprite sprite = mTarget.sprite; + if (sprite == null || sprite.name != mainTranslation) + { + mTarget.sprite = cmp.FindTranslatedObject<Sprite>(mainTranslation); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_RawImage.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_RawImage.cs new file mode 100644 index 0000000..3275190 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_RawImage.cs @@ -0,0 +1,62 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace I2.Loc; + +public class LocalizeTarget_UnityUI_RawImage : LocalizeTarget<RawImage> +{ + static LocalizeTarget_UnityUI_RawImage() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<RawImage, LocalizeTarget_UnityUI_RawImage> + { + Name = "RawImage", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Texture; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override bool CanUseSecondaryTerm() + { + return false; + } + + public override bool AllowMainTermToBeRTL() + { + return false; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = (mTarget.mainTexture ? mTarget.mainTexture.name : ""); + secondaryTerm = null; + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + Texture texture = mTarget.texture; + if (texture == null || texture.name != mainTranslation) + { + mTarget.texture = cmp.FindTranslatedObject<Texture>(mainTranslation); + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_Text.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_Text.cs new file mode 100644 index 0000000..ab26e0d --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizeTarget_UnityUI_Text.cs @@ -0,0 +1,156 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace I2.Loc; + +public class LocalizeTarget_UnityUI_Text : LocalizeTarget<Text> +{ + private TextAnchor mAlignment_RTL = TextAnchor.UpperRight; + + private TextAnchor mAlignment_LTR; + + private bool mAlignmentWasRTL; + + private bool mInitializeAlignment = true; + + static LocalizeTarget_UnityUI_Text() + { + AutoRegister(); + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void AutoRegister() + { + LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<Text, LocalizeTarget_UnityUI_Text> + { + Name = "Text", + Priority = 100 + }); + } + + public override eTermType GetPrimaryTermType(Localize cmp) + { + return eTermType.Text; + } + + public override eTermType GetSecondaryTermType(Localize cmp) + { + return eTermType.Font; + } + + public override bool CanUseSecondaryTerm() + { + return true; + } + + public override bool AllowMainTermToBeRTL() + { + return true; + } + + public override bool AllowSecondTermToBeRTL() + { + return false; + } + + public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm) + { + primaryTerm = (mTarget ? mTarget.text : null); + secondaryTerm = ((mTarget.font != null) ? mTarget.font.name : string.Empty); + } + + public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation) + { + Font secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<Font>(ref mainTranslation, ref secondaryTranslation); + if (secondaryTranslatedObj != null && secondaryTranslatedObj != mTarget.font) + { + mTarget.font = secondaryTranslatedObj; + } + if (mInitializeAlignment) + { + mInitializeAlignment = false; + mAlignmentWasRTL = LocalizationManager.IsRight2Left; + InitAlignment(mAlignmentWasRTL, mTarget.alignment, out mAlignment_LTR, out mAlignment_RTL); + } + else + { + InitAlignment(mAlignmentWasRTL, mTarget.alignment, out var alignLTR, out var alignRTL); + if ((mAlignmentWasRTL && mAlignment_RTL != alignRTL) || (!mAlignmentWasRTL && mAlignment_LTR != alignLTR)) + { + mAlignment_LTR = alignLTR; + mAlignment_RTL = alignRTL; + } + mAlignmentWasRTL = LocalizationManager.IsRight2Left; + } + if (mainTranslation != null && mTarget.text != mainTranslation) + { + if (cmp.CorrectAlignmentForRTL) + { + mTarget.alignment = (LocalizationManager.IsRight2Left ? mAlignment_RTL : mAlignment_LTR); + } + mTarget.text = mainTranslation; + mTarget.SetVerticesDirty(); + } + } + + private void InitAlignment(bool isRTL, TextAnchor alignment, out TextAnchor alignLTR, out TextAnchor alignRTL) + { + alignLTR = (alignRTL = alignment); + if (isRTL) + { + switch (alignment) + { + case TextAnchor.UpperRight: + alignLTR = TextAnchor.UpperLeft; + break; + case TextAnchor.MiddleRight: + alignLTR = TextAnchor.MiddleLeft; + break; + case TextAnchor.LowerRight: + alignLTR = TextAnchor.LowerLeft; + break; + case TextAnchor.UpperLeft: + alignLTR = TextAnchor.UpperRight; + break; + case TextAnchor.MiddleLeft: + alignLTR = TextAnchor.MiddleRight; + break; + case TextAnchor.LowerLeft: + alignLTR = TextAnchor.LowerRight; + break; + case TextAnchor.UpperCenter: + case TextAnchor.MiddleCenter: + case TextAnchor.LowerCenter: + break; + } + } + else + { + switch (alignment) + { + case TextAnchor.UpperRight: + alignRTL = TextAnchor.UpperLeft; + break; + case TextAnchor.MiddleRight: + alignRTL = TextAnchor.MiddleLeft; + break; + case TextAnchor.LowerRight: + alignRTL = TextAnchor.LowerLeft; + break; + case TextAnchor.UpperLeft: + alignRTL = TextAnchor.UpperRight; + break; + case TextAnchor.MiddleLeft: + alignRTL = TextAnchor.MiddleRight; + break; + case TextAnchor.LowerLeft: + alignRTL = TextAnchor.LowerRight; + break; + case TextAnchor.UpperCenter: + case TextAnchor.MiddleCenter: + case TextAnchor.LowerCenter: + break; + } + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/LocalizedString.cs b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizedString.cs new file mode 100644 index 0000000..51ff195 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/LocalizedString.cs @@ -0,0 +1,45 @@ +using System; + +namespace I2.Loc; + +[Serializable] +public struct LocalizedString +{ + public string mTerm; + + public bool mRTL_IgnoreArabicFix; + + public int mRTL_MaxLineLength; + + public bool mRTL_ConvertNumbers; + + public bool m_DontLocalizeParameters; + + public static implicit operator string(LocalizedString s) + { + return s.ToString(); + } + + public static implicit operator LocalizedString(string term) + { + LocalizedString result = default(LocalizedString); + result.mTerm = term; + return result; + } + + public LocalizedString(LocalizedString str) + { + mTerm = str.mTerm; + mRTL_IgnoreArabicFix = str.mRTL_IgnoreArabicFix; + mRTL_MaxLineLength = str.mRTL_MaxLineLength; + mRTL_ConvertNumbers = str.mRTL_ConvertNumbers; + m_DontLocalizeParameters = str.m_DontLocalizeParameters; + } + + public override string ToString() + { + string translation = TextTranslator.Translate(mTerm, !mRTL_IgnoreArabicFix, mRTL_MaxLineLength, !mRTL_ConvertNumbers); + LocalizationManager.ApplyLocalizationParams(ref translation, !m_DontLocalizeParameters); + return translation; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/PersistentStorage.cs b/Thronefall_v1.57/Thronefall/I2.Loc/PersistentStorage.cs new file mode 100644 index 0000000..37854fd --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/PersistentStorage.cs @@ -0,0 +1,104 @@ +namespace I2.Loc; + +public static class PersistentStorage +{ + public enum eFileType + { + Raw, + Persistent, + Temporal, + Streaming + } + + private static I2CustomPersistentStorage mStorage; + + public static void SetSetting_String(string key, string value) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + mStorage.SetSetting_String(key, value); + } + + public static string GetSetting_String(string key, string defaultValue) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + return mStorage.GetSetting_String(key, defaultValue); + } + + public static void DeleteSetting(string key) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + mStorage.DeleteSetting(key); + } + + public static bool HasSetting(string key) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + return mStorage.HasSetting(key); + } + + public static void ForceSaveSettings() + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + mStorage.ForceSaveSettings(); + } + + public static bool CanAccessFiles() + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + return mStorage.CanAccessFiles(); + } + + public static bool SaveFile(eFileType fileType, string fileName, string data, bool logExceptions = true) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + return mStorage.SaveFile(fileType, fileName, data, logExceptions); + } + + public static string LoadFile(eFileType fileType, string fileName, bool logExceptions = true) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + return mStorage.LoadFile(fileType, fileName, logExceptions); + } + + public static bool DeleteFile(eFileType fileType, string fileName, bool logExceptions = true) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + return mStorage.DeleteFile(fileType, fileName, logExceptions); + } + + public static bool HasFile(eFileType fileType, string fileName, bool logExceptions = true) + { + if (mStorage == null) + { + mStorage = new I2CustomPersistentStorage(); + } + return mStorage.HasFile(fileType, fileName, logExceptions); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/RTLFixer.cs b/Thronefall_v1.57/Thronefall/I2.Loc/RTLFixer.cs new file mode 100644 index 0000000..56ccb8b --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/RTLFixer.cs @@ -0,0 +1,79 @@ +using System; + +namespace I2.Loc; + +public class RTLFixer +{ + public static string Fix(string str) + { + return Fix(str, showTashkeel: false, useHinduNumbers: true); + } + + public static string Fix(string str, bool rtl) + { + if (rtl) + { + return Fix(str); + } + string[] array = str.Split(' '); + string text = ""; + string text2 = ""; + string[] array2 = array; + foreach (string text3 in array2) + { + if (char.IsLower(text3.ToLower()[text3.Length / 2])) + { + text = text + Fix(text2) + text3 + " "; + text2 = ""; + } + else + { + text2 = text2 + text3 + " "; + } + } + if (text2 != "") + { + text += Fix(text2); + } + return text; + } + + public static string Fix(string str, bool showTashkeel, bool useHinduNumbers) + { + string text = HindiFixer.Fix(str); + if (text != str) + { + return text; + } + RTLFixerTool.showTashkeel = showTashkeel; + RTLFixerTool.useHinduNumbers = useHinduNumbers; + if (str.Contains("\n")) + { + str = str.Replace("\n", Environment.NewLine); + } + if (str.Contains(Environment.NewLine)) + { + string[] separator = new string[1] { Environment.NewLine }; + string[] array = str.Split(separator, StringSplitOptions.None); + if (array.Length == 0) + { + return RTLFixerTool.FixLine(str); + } + if (array.Length == 1) + { + return RTLFixerTool.FixLine(str); + } + string text2 = RTLFixerTool.FixLine(array[0]); + int i = 1; + if (array.Length > 1) + { + for (; i < array.Length; i++) + { + text2 = text2 + Environment.NewLine + RTLFixerTool.FixLine(array[i]); + } + } + return text2; + } + return RTLFixerTool.FixLine(str); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/RTLFixerTool.cs b/Thronefall_v1.57/Thronefall/I2.Loc/RTLFixerTool.cs new file mode 100644 index 0000000..c0a9b27 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/RTLFixerTool.cs @@ -0,0 +1,404 @@ +using System; +using System.Collections.Generic; + +namespace I2.Loc; + +internal class RTLFixerTool +{ + internal static bool showTashkeel = true; + + internal static bool useHinduNumbers; + + internal static string RemoveTashkeel(string str, out List<TashkeelLocation> tashkeelLocation) + { + tashkeelLocation = new List<TashkeelLocation>(); + char[] array = str.ToCharArray(); + int num = 0; + for (int i = 0; i < array.Length; i++) + { + if (array[i] == '\u064b') + { + tashkeelLocation.Add(new TashkeelLocation('\u064b', i)); + num++; + } + else if (array[i] == '\u064c') + { + tashkeelLocation.Add(new TashkeelLocation('\u064c', i)); + num++; + } + else if (array[i] == '\u064d') + { + tashkeelLocation.Add(new TashkeelLocation('\u064d', i)); + num++; + } + else if (array[i] == '\u064e') + { + if (num > 0 && tashkeelLocation[num - 1].tashkeel == '\u0651') + { + tashkeelLocation[num - 1].tashkeel = 'ﱠ'; + continue; + } + tashkeelLocation.Add(new TashkeelLocation('\u064e', i)); + num++; + } + else if (array[i] == '\u064f') + { + if (num > 0 && tashkeelLocation[num - 1].tashkeel == '\u0651') + { + tashkeelLocation[num - 1].tashkeel = 'ﱡ'; + continue; + } + tashkeelLocation.Add(new TashkeelLocation('\u064f', i)); + num++; + } + else if (array[i] == '\u0650') + { + if (num > 0 && tashkeelLocation[num - 1].tashkeel == '\u0651') + { + tashkeelLocation[num - 1].tashkeel = 'ﱢ'; + continue; + } + tashkeelLocation.Add(new TashkeelLocation('\u0650', i)); + num++; + } + else if (array[i] == '\u0651') + { + if (num > 0) + { + if (tashkeelLocation[num - 1].tashkeel == '\u064e') + { + tashkeelLocation[num - 1].tashkeel = 'ﱠ'; + continue; + } + if (tashkeelLocation[num - 1].tashkeel == '\u064f') + { + tashkeelLocation[num - 1].tashkeel = 'ﱡ'; + continue; + } + if (tashkeelLocation[num - 1].tashkeel == '\u0650') + { + tashkeelLocation[num - 1].tashkeel = 'ﱢ'; + continue; + } + } + tashkeelLocation.Add(new TashkeelLocation('\u0651', i)); + num++; + } + else if (array[i] == '\u0652') + { + tashkeelLocation.Add(new TashkeelLocation('\u0652', i)); + num++; + } + else if (array[i] == '\u0653') + { + tashkeelLocation.Add(new TashkeelLocation('\u0653', i)); + num++; + } + } + string[] array2 = str.Split('\u064b', '\u064c', '\u064d', '\u064e', '\u064f', '\u0650', '\u0651', '\u0652', '\u0653', 'ﱠ', 'ﱡ', 'ﱢ'); + str = ""; + string[] array3 = array2; + foreach (string text in array3) + { + str += text; + } + return str; + } + + internal static char[] ReturnTashkeel(char[] letters, List<TashkeelLocation> tashkeelLocation) + { + char[] array = new char[letters.Length + tashkeelLocation.Count]; + int num = 0; + for (int i = 0; i < letters.Length; i++) + { + array[num] = letters[i]; + num++; + foreach (TashkeelLocation item in tashkeelLocation) + { + if (item.position == num) + { + array[num] = item.tashkeel; + num++; + } + } + } + return array; + } + + internal static string FixLine(string str) + { + string text = ""; + List<TashkeelLocation> tashkeelLocation; + string text2 = RemoveTashkeel(str, out tashkeelLocation); + char[] array = text2.ToCharArray(); + char[] array2 = text2.ToCharArray(); + for (int i = 0; i < array.Length; i++) + { + array[i] = (char)ArabicTable.ArabicMapper.Convert(array[i]); + } + for (int j = 0; j < array.Length; j++) + { + bool flag = false; + if (array[j] == 'ﻝ' && j < array.Length - 1) + { + if (array[j + 1] == 'ﺇ') + { + array[j] = 'ﻷ'; + array2[j + 1] = '\uffff'; + flag = true; + } + else if (array[j + 1] == 'ﺍ') + { + array[j] = 'ﻹ'; + array2[j + 1] = '\uffff'; + flag = true; + } + else if (array[j + 1] == 'ﺃ') + { + array[j] = 'ﻵ'; + array2[j + 1] = '\uffff'; + flag = true; + } + else if (array[j + 1] == 'ﺁ') + { + array[j] = 'ﻳ'; + array2[j + 1] = '\uffff'; + flag = true; + } + } + if (!IsIgnoredCharacter(array[j])) + { + if (IsMiddleLetter(array, j)) + { + array2[j] = (char)(array[j] + 3); + } + else if (IsFinishingLetter(array, j)) + { + array2[j] = (char)(array[j] + 1); + } + else if (IsLeadingLetter(array, j)) + { + array2[j] = (char)(array[j] + 2); + } + } + text = text + Convert.ToString(array[j], 16) + " "; + if (flag) + { + j++; + } + if (useHinduNumbers) + { + if (array[j] == '0') + { + array2[j] = '٠'; + } + else if (array[j] == '1') + { + array2[j] = '١'; + } + else if (array[j] == '2') + { + array2[j] = '٢'; + } + else if (array[j] == '3') + { + array2[j] = '٣'; + } + else if (array[j] == '4') + { + array2[j] = '٤'; + } + else if (array[j] == '5') + { + array2[j] = '٥'; + } + else if (array[j] == '6') + { + array2[j] = '٦'; + } + else if (array[j] == '7') + { + array2[j] = '٧'; + } + else if (array[j] == '8') + { + array2[j] = '٨'; + } + else if (array[j] == '9') + { + array2[j] = '٩'; + } + } + } + if (showTashkeel) + { + array2 = ReturnTashkeel(array2, tashkeelLocation); + } + List<char> list = new List<char>(); + List<char> list2 = new List<char>(); + for (int num = array2.Length - 1; num >= 0; num--) + { + if (char.IsPunctuation(array2[num]) && num > 0 && num < array2.Length - 1 && (char.IsPunctuation(array2[num - 1]) || char.IsPunctuation(array2[num + 1]))) + { + if (array2[num] == '(') + { + list.Add(')'); + } + else if (array2[num] == ')') + { + list.Add('('); + } + else if (array2[num] == '<') + { + list.Add('>'); + } + else if (array2[num] == '>') + { + list.Add('<'); + } + else if (array2[num] == '[') + { + list.Add(']'); + } + else if (array2[num] == ']') + { + list.Add('['); + } + else if (array2[num] != '\uffff') + { + list.Add(array2[num]); + } + } + else if (array2[num] == ' ' && num > 0 && num < array2.Length - 1 && (char.IsLower(array2[num - 1]) || char.IsUpper(array2[num - 1]) || char.IsNumber(array2[num - 1])) && (char.IsLower(array2[num + 1]) || char.IsUpper(array2[num + 1]) || char.IsNumber(array2[num + 1]))) + { + list2.Add(array2[num]); + } + else if (char.IsNumber(array2[num]) || char.IsLower(array2[num]) || char.IsUpper(array2[num]) || char.IsSymbol(array2[num]) || char.IsPunctuation(array2[num])) + { + if (array2[num] == '(') + { + list2.Add(')'); + } + else if (array2[num] == ')') + { + list2.Add('('); + } + else if (array2[num] == '<') + { + list2.Add('>'); + } + else if (array2[num] == '>') + { + list2.Add('<'); + } + else if (array2[num] == '[') + { + list.Add(']'); + } + else if (array2[num] == ']') + { + list.Add('['); + } + else + { + list2.Add(array2[num]); + } + } + else if ((array2[num] >= '\ud800' && array2[num] <= '\udbff') || (array2[num] >= '\udc00' && array2[num] <= '\udfff')) + { + list2.Add(array2[num]); + } + else + { + if (list2.Count > 0) + { + for (int k = 0; k < list2.Count; k++) + { + list.Add(list2[list2.Count - 1 - k]); + } + list2.Clear(); + } + if (array2[num] != '\uffff') + { + list.Add(array2[num]); + } + } + } + if (list2.Count > 0) + { + for (int l = 0; l < list2.Count; l++) + { + list.Add(list2[list2.Count - 1 - l]); + } + list2.Clear(); + } + array2 = new char[list.Count]; + for (int m = 0; m < array2.Length; m++) + { + array2[m] = list[m]; + } + str = new string(array2); + return str; + } + + internal static bool IsIgnoredCharacter(char ch) + { + bool num = char.IsPunctuation(ch); + bool flag = char.IsNumber(ch); + bool flag2 = char.IsLower(ch); + bool flag3 = char.IsUpper(ch); + bool flag4 = char.IsSymbol(ch); + bool flag5 = ch == 'ﭖ' || ch == 'ﭺ' || ch == 'ﮊ' || ch == 'ﮒ' || ch == 'ﮎ'; + bool flag6 = (ch <= '\ufeff' && ch >= 'ﹰ') || flag5 || ch == 'ﯼ'; + if (!(num || flag || flag2 || flag3 || flag4) && flag6 && ch != 'a' && ch != '>' && ch != '<') + { + return ch == '؛'; + } + return true; + } + + internal static bool IsLeadingLetter(char[] letters, int index) + { + bool num = index == 0 || letters[index - 1] == ' ' || letters[index - 1] == '*' || letters[index - 1] == 'A' || char.IsPunctuation(letters[index - 1]) || letters[index - 1] == '>' || letters[index - 1] == '<' || letters[index - 1] == 'ﺍ' || letters[index - 1] == 'ﺩ' || letters[index - 1] == 'ﺫ' || letters[index - 1] == 'ﺭ' || letters[index - 1] == 'ﺯ' || letters[index - 1] == 'ﮊ' || letters[index - 1] == 'ﻭ' || letters[index - 1] == 'ﺁ' || letters[index - 1] == 'ﺃ' || letters[index - 1] == 'ﺇ' || letters[index - 1] == 'ﺅ'; + bool flag = letters[index] != ' ' && letters[index] != 'ﺩ' && letters[index] != 'ﺫ' && letters[index] != 'ﺭ' && letters[index] != 'ﺯ' && letters[index] != 'ﮊ' && letters[index] != 'ﺍ' && letters[index] != 'ﺃ' && letters[index] != 'ﺇ' && letters[index] != 'ﺁ' && letters[index] != 'ﺅ' && letters[index] != 'ﻭ' && letters[index] != 'ﺀ'; + bool flag2 = index < letters.Length - 1 && letters[index + 1] != ' ' && !char.IsPunctuation(letters[index + 1]) && !char.IsNumber(letters[index + 1]) && !char.IsSymbol(letters[index + 1]) && !char.IsLower(letters[index + 1]) && !char.IsUpper(letters[index + 1]) && letters[index + 1] != 'ﺀ'; + if (num && flag && flag2) + { + return true; + } + return false; + } + + internal static bool IsFinishingLetter(char[] letters, int index) + { + bool num = index != 0 && letters[index - 1] != ' ' && letters[index - 1] != 'ﺩ' && letters[index - 1] != 'ﺫ' && letters[index - 1] != 'ﺭ' && letters[index - 1] != 'ﺯ' && letters[index - 1] != 'ﮊ' && letters[index - 1] != 'ﻭ' && letters[index - 1] != 'ﺍ' && letters[index - 1] != 'ﺁ' && letters[index - 1] != 'ﺃ' && letters[index - 1] != 'ﺇ' && letters[index - 1] != 'ﺅ' && letters[index - 1] != 'ﺀ' && !char.IsPunctuation(letters[index - 1]) && letters[index - 1] != '>' && letters[index - 1] != '<'; + bool flag = letters[index] != ' ' && letters[index] != 'ﺀ'; + if (num && flag) + { + return true; + } + return false; + } + + internal static bool IsMiddleLetter(char[] letters, int index) + { + bool flag = index != 0 && letters[index] != 'ﺍ' && letters[index] != 'ﺩ' && letters[index] != 'ﺫ' && letters[index] != 'ﺭ' && letters[index] != 'ﺯ' && letters[index] != 'ﮊ' && letters[index] != 'ﻭ' && letters[index] != 'ﺁ' && letters[index] != 'ﺃ' && letters[index] != 'ﺇ' && letters[index] != 'ﺅ' && letters[index] != 'ﺀ'; + bool flag2 = index != 0 && letters[index - 1] != 'ﺍ' && letters[index - 1] != 'ﺩ' && letters[index - 1] != 'ﺫ' && letters[index - 1] != 'ﺭ' && letters[index - 1] != 'ﺯ' && letters[index - 1] != 'ﮊ' && letters[index - 1] != 'ﻭ' && letters[index - 1] != 'ﺁ' && letters[index - 1] != 'ﺃ' && letters[index - 1] != 'ﺇ' && letters[index - 1] != 'ﺅ' && letters[index - 1] != 'ﺀ' && !char.IsPunctuation(letters[index - 1]) && letters[index - 1] != '>' && letters[index - 1] != '<' && letters[index - 1] != ' ' && letters[index - 1] != '*'; + if (index < letters.Length - 1 && letters[index + 1] != ' ' && letters[index + 1] != '\r' && letters[index + 1] != 'ﺀ' && !char.IsNumber(letters[index + 1]) && !char.IsSymbol(letters[index + 1]) && !char.IsPunctuation(letters[index + 1]) && flag2 && flag) + { + try + { + if (char.IsPunctuation(letters[index + 1])) + { + return false; + } + return true; + } + catch + { + return false; + } + } + return false; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/RealTimeTranslation.cs b/Thronefall_v1.57/Thronefall/I2.Loc/RealTimeTranslation.cs new file mode 100644 index 0000000..d0bee68 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/RealTimeTranslation.cs @@ -0,0 +1,118 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace I2.Loc; + +public class RealTimeTranslation : MonoBehaviour +{ + private string OriginalText = "This is an example showing how to use the google translator to translate chat messages within the game.\nIt also supports multiline translations."; + + private string TranslatedText = string.Empty; + + private bool IsTranslating; + + public void OnGUI() + { + GUILayout.Label("Translate:"); + OriginalText = GUILayout.TextArea(OriginalText, GUILayout.Width(Screen.width)); + GUILayout.Space(10f); + GUILayout.BeginHorizontal(); + if (GUILayout.Button("English -> Español", GUILayout.Height(100f))) + { + StartTranslating("en", "es"); + } + if (GUILayout.Button("Español -> English", GUILayout.Height(100f))) + { + StartTranslating("es", "en"); + } + GUILayout.EndHorizontal(); + GUILayout.Space(10f); + GUILayout.BeginHorizontal(); + GUILayout.TextArea("Multiple Translation with 1 call:\n'This is an example' -> en,zh\n'Hola' -> en"); + if (GUILayout.Button("Multi Translate", GUILayout.ExpandHeight(expand: true))) + { + ExampleMultiTranslations_Async(); + } + GUILayout.EndHorizontal(); + GUILayout.TextArea(TranslatedText, GUILayout.Width(Screen.width)); + GUILayout.Space(10f); + if (IsTranslating) + { + GUILayout.Label("Contacting Google...."); + } + } + + public void StartTranslating(string fromCode, string toCode) + { + IsTranslating = true; + GoogleTranslation.Translate(OriginalText, fromCode, toCode, OnTranslationReady); + } + + private void OnTranslationReady(string Translation, string errorMsg) + { + IsTranslating = false; + if (errorMsg != null) + { + Debug.LogError(errorMsg); + } + else + { + TranslatedText = Translation; + } + } + + public void ExampleMultiTranslations_Blocking() + { + Dictionary<string, TranslationQuery> dictionary = new Dictionary<string, TranslationQuery>(); + GoogleTranslation.AddQuery("This is an example", "en", "es", dictionary); + GoogleTranslation.AddQuery("This is an example", "auto", "zh", dictionary); + GoogleTranslation.AddQuery("Hola", "es", "en", dictionary); + if (GoogleTranslation.ForceTranslate(dictionary)) + { + Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "en", dictionary)); + Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "zh", dictionary)); + Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "", dictionary)); + Debug.Log(dictionary["Hola"].Results[0]); + } + } + + public void ExampleMultiTranslations_Async() + { + IsTranslating = true; + Dictionary<string, TranslationQuery> dictionary = new Dictionary<string, TranslationQuery>(); + GoogleTranslation.AddQuery("This is an example", "en", "es", dictionary); + GoogleTranslation.AddQuery("This is an example", "auto", "zh", dictionary); + GoogleTranslation.AddQuery("Hola", "es", "en", dictionary); + GoogleTranslation.Translate(dictionary, OnMultitranslationReady); + } + + private void OnMultitranslationReady(Dictionary<string, TranslationQuery> dict, string errorMsg) + { + if (!string.IsNullOrEmpty(errorMsg)) + { + Debug.LogError(errorMsg); + return; + } + IsTranslating = false; + TranslatedText = ""; + TranslatedText = TranslatedText + GoogleTranslation.GetQueryResult("This is an example", "es", dict) + "\n"; + TranslatedText = TranslatedText + GoogleTranslation.GetQueryResult("This is an example", "zh", dict) + "\n"; + TranslatedText = TranslatedText + GoogleTranslation.GetQueryResult("This is an example", "", dict) + "\n"; + TranslatedText += dict["Hola"].Results[0]; + } + + public bool IsWaitingForTranslation() + { + return IsTranslating; + } + + public string GetTranslatedText() + { + return TranslatedText; + } + + public void SetOriginalText(string text) + { + OriginalText = text; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/RegisterBundlesManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/RegisterBundlesManager.cs new file mode 100644 index 0000000..e475810 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/RegisterBundlesManager.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +namespace I2.Loc; + +public class RegisterBundlesManager : MonoBehaviour, IResourceManager_Bundles +{ + public void OnEnable() + { + if (!ResourceManager.pInstance.mBundleManagers.Contains(this)) + { + ResourceManager.pInstance.mBundleManagers.Add(this); + } + } + + public void OnDisable() + { + ResourceManager.pInstance.mBundleManagers.Remove(this); + } + + public virtual UnityEngine.Object LoadFromBundle(string path, Type assetType) + { + return null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/RegisterCallback_AllowSyncFromGoogle.cs b/Thronefall_v1.57/Thronefall/I2.Loc/RegisterCallback_AllowSyncFromGoogle.cs new file mode 100644 index 0000000..039dc18 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/RegisterCallback_AllowSyncFromGoogle.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +namespace I2.Loc; + +public class RegisterCallback_AllowSyncFromGoogle : MonoBehaviour +{ + public void Awake() + { + LocalizationManager.Callback_AllowSyncFromGoogle = AllowSyncFromGoogle; + } + + public void OnEnable() + { + LocalizationManager.Callback_AllowSyncFromGoogle = AllowSyncFromGoogle; + } + + public void OnDisable() + { + LocalizationManager.Callback_AllowSyncFromGoogle = null; + } + + public virtual bool AllowSyncFromGoogle(LanguageSourceData Source) + { + return true; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/RegisterGlobalParameters.cs b/Thronefall_v1.57/Thronefall/I2.Loc/RegisterGlobalParameters.cs new file mode 100644 index 0000000..4642977 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/RegisterGlobalParameters.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +namespace I2.Loc; + +public class RegisterGlobalParameters : MonoBehaviour, ILocalizationParamsManager +{ + public virtual void OnEnable() + { + if (!LocalizationManager.ParamManagers.Contains(this)) + { + LocalizationManager.ParamManagers.Add(this); + LocalizationManager.LocalizeAll(Force: true); + } + } + + public virtual void OnDisable() + { + LocalizationManager.ParamManagers.Remove(this); + } + + public virtual string GetParameterValue(string ParamName) + { + return null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ResourceManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ResourceManager.cs new file mode 100644 index 0000000..793bb21 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ResourceManager.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace I2.Loc; + +public class ResourceManager : MonoBehaviour +{ + private static ResourceManager mInstance; + + public List<IResourceManager_Bundles> mBundleManagers = new List<IResourceManager_Bundles>(); + + public UnityEngine.Object[] Assets; + + private readonly Dictionary<string, UnityEngine.Object> mResourcesCache = new Dictionary<string, UnityEngine.Object>(StringComparer.Ordinal); + + public static ResourceManager pInstance + { + get + { + bool flag = mInstance == null; + if (mInstance == null) + { + mInstance = (ResourceManager)UnityEngine.Object.FindObjectOfType(typeof(ResourceManager)); + } + if (mInstance == null) + { + GameObject obj = new GameObject("I2ResourceManager", typeof(ResourceManager)); + obj.hideFlags |= HideFlags.HideAndDontSave; + mInstance = obj.GetComponent<ResourceManager>(); + SceneManager.sceneLoaded += MyOnLevelWasLoaded; + } + if (flag && Application.isPlaying) + { + UnityEngine.Object.DontDestroyOnLoad(mInstance.gameObject); + } + return mInstance; + } + } + + public static void MyOnLevelWasLoaded(Scene scene, LoadSceneMode mode) + { + pInstance.CleanResourceCache(); + LocalizationManager.UpdateSources(); + } + + public T GetAsset<T>(string Name) where T : UnityEngine.Object + { + T val = FindAsset(Name) as T; + if ((UnityEngine.Object)val != (UnityEngine.Object)null) + { + return val; + } + return LoadFromResources<T>(Name); + } + + private UnityEngine.Object FindAsset(string Name) + { + if (Assets != null) + { + int i = 0; + for (int num = Assets.Length; i < num; i++) + { + if (Assets[i] != null && Assets[i].name == Name) + { + return Assets[i]; + } + } + } + return null; + } + + public bool HasAsset(UnityEngine.Object Obj) + { + if (Assets == null) + { + return false; + } + return Array.IndexOf(Assets, Obj) >= 0; + } + + public T LoadFromResources<T>(string Path) where T : UnityEngine.Object + { + try + { + if (string.IsNullOrEmpty(Path)) + { + return null; + } + if (mResourcesCache.TryGetValue(Path, out var value) && value != null) + { + return value as T; + } + T val = null; + if (Path.EndsWith("]", StringComparison.OrdinalIgnoreCase)) + { + int num = Path.LastIndexOf("[", StringComparison.OrdinalIgnoreCase); + int length = Path.Length - num - 2; + string value2 = Path.Substring(num + 1, length); + Path = Path.Substring(0, num); + T[] array = Resources.LoadAll<T>(Path); + int i = 0; + for (int num2 = array.Length; i < num2; i++) + { + if (array[i].name.Equals(value2)) + { + val = array[i]; + break; + } + } + } + else + { + val = Resources.Load(Path, typeof(T)) as T; + } + if ((UnityEngine.Object)val == (UnityEngine.Object)null) + { + val = LoadFromBundle<T>(Path); + } + if ((UnityEngine.Object)val != (UnityEngine.Object)null) + { + mResourcesCache[Path] = val; + } + return val; + } + catch (Exception ex) + { + Debug.LogErrorFormat("Unable to load {0} '{1}'\nERROR: {2}", typeof(T), Path, ex.ToString()); + return null; + } + } + + public T LoadFromBundle<T>(string path) where T : UnityEngine.Object + { + int i = 0; + for (int count = mBundleManagers.Count; i < count; i++) + { + if (mBundleManagers[i] != null) + { + T val = mBundleManagers[i].LoadFromBundle(path, typeof(T)) as T; + if ((UnityEngine.Object)val != (UnityEngine.Object)null) + { + return val; + } + } + } + return null; + } + + public void CleanResourceCache(bool unloadResources = false) + { + mResourcesCache.Clear(); + if (unloadResources) + { + Resources.UnloadUnusedAssets(); + } + CancelInvoke(); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/SetLanguage.cs b/Thronefall_v1.57/Thronefall/I2.Loc/SetLanguage.cs new file mode 100644 index 0000000..108efdc --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/SetLanguage.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +namespace I2.Loc; + +[AddComponentMenu("I2/Localization/SetLanguage Button")] +public class SetLanguage : MonoBehaviour +{ + public string _Language; + + private void OnClick() + { + ApplyLanguage(); + } + + public void ApplyLanguage() + { + if (LocalizationManager.HasLanguage(_Language)) + { + LocalizationManager.CurrentLanguage = _Language; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/SetLanguageDropdown.cs b/Thronefall_v1.57/Thronefall/I2.Loc/SetLanguageDropdown.cs new file mode 100644 index 0000000..4175b4f --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/SetLanguageDropdown.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace I2.Loc; + +[AddComponentMenu("I2/Localization/SetLanguage Dropdown")] +public class SetLanguageDropdown : MonoBehaviour +{ + private void OnEnable() + { + Dropdown component = GetComponent<Dropdown>(); + if (!(component == null)) + { + string currentLanguage = LocalizationManager.CurrentLanguage; + if (LocalizationManager.Sources.Count == 0) + { + LocalizationManager.UpdateSources(); + } + List<string> allLanguages = LocalizationManager.GetAllLanguages(); + component.ClearOptions(); + component.AddOptions(allLanguages); + component.value = allLanguages.IndexOf(currentLanguage); + component.onValueChanged.RemoveListener(OnValueChanged); + component.onValueChanged.AddListener(OnValueChanged); + } + } + + private void OnValueChanged(int index) + { + Dropdown component = GetComponent<Dropdown>(); + if (index < 0) + { + index = 0; + component.value = index; + } + LocalizationManager.CurrentLanguage = component.options[index].text; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/SpecializationManager.cs b/Thronefall_v1.57/Thronefall/I2.Loc/SpecializationManager.cs new file mode 100644 index 0000000..93515a5 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/SpecializationManager.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; + +namespace I2.Loc; + +public class SpecializationManager : BaseSpecializationManager +{ + public static SpecializationManager Singleton = new SpecializationManager(); + + private SpecializationManager() + { + InitializeSpecializations(); + } + + public static string GetSpecializedText(string text, string specialization = null) + { + int num = text.IndexOf("[i2s_", StringComparison.Ordinal); + if (num < 0) + { + return text; + } + if (string.IsNullOrEmpty(specialization)) + { + specialization = Singleton.GetCurrentSpecialization(); + } + while (!string.IsNullOrEmpty(specialization) && specialization != "Any") + { + string text2 = "[i2s_" + specialization + "]"; + int num2 = text.IndexOf(text2, StringComparison.Ordinal); + if (num2 < 0) + { + specialization = Singleton.GetFallbackSpecialization(specialization); + continue; + } + num2 += text2.Length; + int num3 = text.IndexOf("[i2s_", num2, StringComparison.Ordinal); + if (num3 < 0) + { + num3 = text.Length; + } + return text.Substring(num2, num3 - num2); + } + return text.Substring(0, num); + } + + public static string SetSpecializedText(string text, string newText, string specialization) + { + if (string.IsNullOrEmpty(specialization)) + { + specialization = "Any"; + } + if ((text == null || !text.Contains("[i2s_")) && specialization == "Any") + { + return newText; + } + Dictionary<string, string> specializations = GetSpecializations(text); + specializations[specialization] = newText; + return SetSpecializedText(specializations); + } + + public static string SetSpecializedText(Dictionary<string, string> specializations) + { + if (!specializations.TryGetValue("Any", out var value)) + { + value = string.Empty; + } + foreach (KeyValuePair<string, string> specialization in specializations) + { + if (specialization.Key != "Any" && !string.IsNullOrEmpty(specialization.Value)) + { + value = value + "[i2s_" + specialization.Key + "]" + specialization.Value; + } + } + return value; + } + + public static Dictionary<string, string> GetSpecializations(string text, Dictionary<string, string> buffer = null) + { + if (buffer == null) + { + buffer = new Dictionary<string, string>(StringComparer.Ordinal); + } + else + { + buffer.Clear(); + } + if (text == null) + { + buffer["Any"] = ""; + return buffer; + } + int num = 0; + int num2 = text.IndexOf("[i2s_", StringComparison.Ordinal); + if (num2 < 0) + { + num2 = text.Length; + } + buffer["Any"] = text.Substring(0, num2); + for (num = num2; num < text.Length; num = num2) + { + num += "[i2s_".Length; + int num3 = text.IndexOf(']', num); + if (num3 < 0) + { + break; + } + string key = text.Substring(num, num3 - num); + num = num3 + 1; + num2 = text.IndexOf("[i2s_", num, StringComparison.Ordinal); + if (num2 < 0) + { + num2 = text.Length; + } + string value = text.Substring(num, num2 - num); + buffer[key] = value; + } + return buffer; + } + + public static void AppendSpecializations(string text, List<string> list = null) + { + if (text == null) + { + return; + } + if (list == null) + { + list = new List<string>(); + } + if (!list.Contains("Any")) + { + list.Add("Any"); + } + int num = 0; + while (num < text.Length) + { + num = text.IndexOf("[i2s_", num, StringComparison.Ordinal); + if (num >= 0) + { + num += "[i2s_".Length; + int num2 = text.IndexOf(']', num); + if (num2 >= 0) + { + string item = text.Substring(num, num2 - num); + if (!list.Contains(item)) + { + list.Add(item); + } + continue; + } + break; + } + break; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/StringObfucator.cs b/Thronefall_v1.57/Thronefall/I2.Loc/StringObfucator.cs new file mode 100644 index 0000000..4f054ef --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/StringObfucator.cs @@ -0,0 +1,64 @@ +using System; +using System.Text; + +namespace I2.Loc; + +public class StringObfucator +{ + public static char[] StringObfuscatorPassword = "ÝúbUu\u00b8CÁ§*4PÚ©-᩾@T6Dl±ÒWâuzÅm4GÐóØ$=Íg,¥Që®iKEßr¡×60Ít4öÃ~^«y:Èd1<QÛÝúbUu\u00b8CÁ§*4PÚ©-᩾@T6Dl±ÒWâuzÅm4GÐóØ$=Íg,¥Që®iKEßr¡×60Ít4öÃ~^«y:Èd".ToCharArray(); + + public static string Encode(string NormalString) + { + try + { + return ToBase64(XoREncode(NormalString)); + } + catch (Exception) + { + return null; + } + } + + public static string Decode(string ObfucatedString) + { + try + { + return XoREncode(FromBase64(ObfucatedString)); + } + catch (Exception) + { + return null; + } + } + + private static string ToBase64(string regularString) + { + return Convert.ToBase64String(Encoding.UTF8.GetBytes(regularString)); + } + + private static string FromBase64(string base64string) + { + byte[] array = Convert.FromBase64String(base64string); + return Encoding.UTF8.GetString(array, 0, array.Length); + } + + private static string XoREncode(string NormalString) + { + try + { + char[] stringObfuscatorPassword = StringObfuscatorPassword; + char[] array = NormalString.ToCharArray(); + int num = stringObfuscatorPassword.Length; + int i = 0; + for (int num2 = array.Length; i < num2; i++) + { + array[i] = (char)(array[i] ^ stringObfuscatorPassword[i % num] ^ (byte)((i % 2 == 0) ? (i * 23) : (-i * 51))); + } + return new string(array); + } + catch (Exception) + { + return null; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TashkeelLocation.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TashkeelLocation.cs new file mode 100644 index 0000000..ac6f3a4 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TashkeelLocation.cs @@ -0,0 +1,14 @@ +namespace I2.Loc; + +internal class TashkeelLocation +{ + public char tashkeel; + + public int position; + + public TashkeelLocation(char tashkeel, int position) + { + this.tashkeel = tashkeel; + this.position = position; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TermData.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TermData.cs new file mode 100644 index 0000000..6827525 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TermData.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace I2.Loc; + +[Serializable] +public class TermData +{ + public string Term = string.Empty; + + public eTermType TermType; + + [NonSerialized] + public string Description; + + public string[] Languages = Array.Empty<string>(); + + public byte[] Flags = Array.Empty<byte>(); + + [SerializeField] + private string[] Languages_Touch; + + public string GetTranslation(int idx, string specialization = null, bool editMode = false) + { + string text = Languages[idx]; + if (text != null) + { + text = SpecializationManager.GetSpecializedText(text, specialization); + if (!editMode) + { + text = text.Replace("[i2nt]", "").Replace("[/i2nt]", ""); + } + } + return text; + } + + public void SetTranslation(int idx, string translation, string specialization = null) + { + Languages[idx] = SpecializationManager.SetSpecializedText(Languages[idx], translation, specialization); + } + + public void RemoveSpecialization(string specialization) + { + for (int i = 0; i < Languages.Length; i++) + { + RemoveSpecialization(i, specialization); + } + } + + public void RemoveSpecialization(int idx, string specialization) + { + string text = Languages[idx]; + if (!(specialization == "Any") && text.Contains("[i2s_" + specialization + "]")) + { + Dictionary<string, string> specializations = SpecializationManager.GetSpecializations(text); + specializations.Remove(specialization); + Languages[idx] = SpecializationManager.SetSpecializedText(specializations); + } + } + + public bool IsAutoTranslated(int idx, bool IsTouch) + { + return (Flags[idx] & 2) > 0; + } + + public void Validate() + { + int num = Mathf.Max(Languages.Length, Flags.Length); + if (Languages.Length != num) + { + Array.Resize(ref Languages, num); + } + if (Flags.Length != num) + { + Array.Resize(ref Flags, num); + } + if (Languages_Touch == null) + { + return; + } + for (int i = 0; i < Mathf.Min(Languages_Touch.Length, num); i++) + { + if (string.IsNullOrEmpty(Languages[i]) && !string.IsNullOrEmpty(Languages_Touch[i])) + { + Languages[i] = Languages_Touch[i]; + Languages_Touch[i] = null; + } + } + Languages_Touch = null; + } + + public bool IsTerm(string name, bool allowCategoryMistmatch) + { + if (!allowCategoryMistmatch) + { + return name == Term; + } + return name == LanguageSourceData.GetKeyFromFullTerm(Term); + } + + public bool HasSpecializations() + { + for (int i = 0; i < Languages.Length; i++) + { + if (!string.IsNullOrEmpty(Languages[i]) && Languages[i].Contains("[i2s_")) + { + return true; + } + } + return false; + } + + public List<string> GetAllSpecializations() + { + List<string> list = new List<string>(); + for (int i = 0; i < Languages.Length; i++) + { + SpecializationManager.AppendSpecializations(Languages[i], list); + } + return list; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TermsPopup.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TermsPopup.cs new file mode 100644 index 0000000..827e495 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TermsPopup.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +namespace I2.Loc; + +public class TermsPopup : PropertyAttribute +{ + public string Filter { get; private set; } + + public TermsPopup(string filter = "") + { + Filter = filter; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ToggleLanguage.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ToggleLanguage.cs new file mode 100644 index 0000000..881e0fe --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ToggleLanguage.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace I2.Loc; + +public class ToggleLanguage : MonoBehaviour +{ + private void Start() + { + Invoke("test", 3f); + } + + private void test() + { + List<string> allLanguages = LocalizationManager.GetAllLanguages(); + int num = allLanguages.IndexOf(LocalizationManager.CurrentLanguage); + if (num < 0) + { + num = 0; + } + else + { + num = (num + 1) % allLanguages.Count; + } + Invoke("test", 3f); + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationFlag.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationFlag.cs new file mode 100644 index 0000000..c2c705b --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationFlag.cs @@ -0,0 +1,7 @@ +namespace I2.Loc; + +public enum TranslationFlag : byte +{ + Normal = 1, + AutoTranslated +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob.cs new file mode 100644 index 0000000..a93545d --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob.cs @@ -0,0 +1,24 @@ +using System; + +namespace I2.Loc; + +public class TranslationJob : IDisposable +{ + public enum eJobState + { + Running, + Succeeded, + Failed + } + + public eJobState mJobState; + + public virtual eJobState GetState() + { + return mJobState; + } + + public virtual void Dispose() + { + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_GET.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_GET.cs new file mode 100644 index 0000000..d224401 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_GET.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Text; +using UnityEngine.Networking; + +namespace I2.Loc; + +public class TranslationJob_GET : TranslationJob_WWW +{ + private Dictionary<string, TranslationQuery> _requests; + + private GoogleTranslation.fnOnTranslationReady _OnTranslationReady; + + private List<string> mQueries; + + public string mErrorMessage; + + public TranslationJob_GET(Dictionary<string, TranslationQuery> requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady) + { + _requests = requests; + _OnTranslationReady = OnTranslationReady; + mQueries = GoogleTranslation.ConvertTranslationRequest(requests, encodeGET: true); + GetState(); + } + + private void ExecuteNextQuery() + { + if (mQueries.Count == 0) + { + mJobState = eJobState.Succeeded; + return; + } + int index = mQueries.Count - 1; + string text = mQueries[index]; + mQueries.RemoveAt(index); + string uri = LocalizationManager.GetWebServiceURL() + "?action=Translate&list=" + text; + www = UnityWebRequest.Get(uri); + I2Utils.SendWebRequest(www); + } + + public override eJobState GetState() + { + if (www != null && www.isDone) + { + ProcessResult(www.downloadHandler.data, www.error); + www.Dispose(); + www = null; + } + if (www == null) + { + ExecuteNextQuery(); + } + return mJobState; + } + + public void ProcessResult(byte[] bytes, string errorMsg) + { + if (string.IsNullOrEmpty(errorMsg)) + { + errorMsg = GoogleTranslation.ParseTranslationResult(Encoding.UTF8.GetString(bytes, 0, bytes.Length), _requests); + if (string.IsNullOrEmpty(errorMsg)) + { + if (_OnTranslationReady != null) + { + _OnTranslationReady(_requests, null); + } + return; + } + } + mJobState = eJobState.Failed; + mErrorMessage = errorMsg; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_Main.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_Main.cs new file mode 100644 index 0000000..595872a --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_Main.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; + +namespace I2.Loc; + +public class TranslationJob_Main : TranslationJob +{ + private TranslationJob_WEB mWeb; + + private TranslationJob_POST mPost; + + private TranslationJob_GET mGet; + + private Dictionary<string, TranslationQuery> _requests; + + private GoogleTranslation.fnOnTranslationReady _OnTranslationReady; + + public string mErrorMessage; + + public TranslationJob_Main(Dictionary<string, TranslationQuery> requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady) + { + _requests = requests; + _OnTranslationReady = OnTranslationReady; + mPost = new TranslationJob_POST(requests, OnTranslationReady); + } + + public override eJobState GetState() + { + if (mWeb != null) + { + switch (mWeb.GetState()) + { + case eJobState.Running: + return eJobState.Running; + case eJobState.Succeeded: + mJobState = eJobState.Succeeded; + break; + case eJobState.Failed: + mWeb.Dispose(); + mWeb = null; + mPost = new TranslationJob_POST(_requests, _OnTranslationReady); + break; + } + } + if (mPost != null) + { + switch (mPost.GetState()) + { + case eJobState.Running: + return eJobState.Running; + case eJobState.Succeeded: + mJobState = eJobState.Succeeded; + break; + case eJobState.Failed: + mPost.Dispose(); + mPost = null; + mGet = new TranslationJob_GET(_requests, _OnTranslationReady); + break; + } + } + if (mGet != null) + { + switch (mGet.GetState()) + { + case eJobState.Running: + return eJobState.Running; + case eJobState.Succeeded: + mJobState = eJobState.Succeeded; + break; + case eJobState.Failed: + mErrorMessage = mGet.mErrorMessage; + if (_OnTranslationReady != null) + { + _OnTranslationReady(_requests, mErrorMessage); + } + mGet.Dispose(); + mGet = null; + break; + } + } + return mJobState; + } + + public override void Dispose() + { + if (mPost != null) + { + mPost.Dispose(); + } + if (mGet != null) + { + mGet.Dispose(); + } + mPost = null; + mGet = null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_POST.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_POST.cs new file mode 100644 index 0000000..561cb90 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_POST.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Text; +using UnityEngine; +using UnityEngine.Networking; + +namespace I2.Loc; + +public class TranslationJob_POST : TranslationJob_WWW +{ + private Dictionary<string, TranslationQuery> _requests; + + private GoogleTranslation.fnOnTranslationReady _OnTranslationReady; + + public TranslationJob_POST(Dictionary<string, TranslationQuery> requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady) + { + _requests = requests; + _OnTranslationReady = OnTranslationReady; + List<string> list = GoogleTranslation.ConvertTranslationRequest(requests, encodeGET: false); + WWWForm wWWForm = new WWWForm(); + wWWForm.AddField("action", "Translate"); + wWWForm.AddField("list", list[0]); + www = UnityWebRequest.Post(LocalizationManager.GetWebServiceURL(), wWWForm); + I2Utils.SendWebRequest(www); + } + + public override eJobState GetState() + { + if (www != null && www.isDone) + { + ProcessResult(www.downloadHandler.data, www.error); + www.Dispose(); + www = null; + } + return mJobState; + } + + public void ProcessResult(byte[] bytes, string errorMsg) + { + if (!string.IsNullOrEmpty(errorMsg)) + { + mJobState = eJobState.Failed; + return; + } + errorMsg = GoogleTranslation.ParseTranslationResult(Encoding.UTF8.GetString(bytes, 0, bytes.Length), _requests); + if (_OnTranslationReady != null) + { + _OnTranslationReady(_requests, errorMsg); + } + mJobState = eJobState.Succeeded; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_WEB.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_WEB.cs new file mode 100644 index 0000000..4136e38 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_WEB.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEngine.Networking; + +namespace I2.Loc; + +public class TranslationJob_WEB : TranslationJob_WWW +{ + private Dictionary<string, TranslationQuery> _requests; + + private GoogleTranslation.fnOnTranslationReady _OnTranslationReady; + + public string mErrorMessage; + + private string mCurrentBatch_ToLanguageCode; + + private string mCurrentBatch_FromLanguageCode; + + private List<string> mCurrentBatch_Text; + + private List<KeyValuePair<string, string>> mQueries; + + public TranslationJob_WEB(Dictionary<string, TranslationQuery> requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady) + { + _requests = requests; + _OnTranslationReady = OnTranslationReady; + FindAllQueries(); + ExecuteNextBatch(); + } + + private void FindAllQueries() + { + mQueries = new List<KeyValuePair<string, string>>(); + foreach (KeyValuePair<string, TranslationQuery> request in _requests) + { + string[] targetLanguagesCode = request.Value.TargetLanguagesCode; + foreach (string text in targetLanguagesCode) + { + mQueries.Add(new KeyValuePair<string, string>(request.Value.OrigText, request.Value.LanguageCode + ":" + text)); + } + } + mQueries.Sort((KeyValuePair<string, string> a, KeyValuePair<string, string> b) => a.Value.CompareTo(b.Value)); + } + + private void ExecuteNextBatch() + { + if (mQueries.Count == 0) + { + mJobState = eJobState.Succeeded; + return; + } + mCurrentBatch_Text = new List<string>(); + string text = null; + int num = 200; + StringBuilder stringBuilder = new StringBuilder(); + int i; + for (i = 0; i < mQueries.Count; i++) + { + string key = mQueries[i].Key; + string value = mQueries[i].Value; + if (text == null || value == text) + { + if (i != 0) + { + stringBuilder.Append("|||"); + } + stringBuilder.Append(key); + mCurrentBatch_Text.Add(key); + text = value; + } + if (stringBuilder.Length > num) + { + break; + } + } + mQueries.RemoveRange(0, i); + string[] array = text.Split(':'); + mCurrentBatch_FromLanguageCode = array[0]; + mCurrentBatch_ToLanguageCode = array[1]; + string text2 = $"http://www.google.com/translate_t?hl=en&vi=c&ie=UTF8&oe=UTF8&submit=Translate&langpair={mCurrentBatch_FromLanguageCode}|{mCurrentBatch_ToLanguageCode}&text={Uri.EscapeUriString(stringBuilder.ToString())}"; + Debug.Log(text2); + www = UnityWebRequest.Get(text2); + I2Utils.SendWebRequest(www); + } + + public override eJobState GetState() + { + if (www != null && www.isDone) + { + ProcessResult(www.downloadHandler.data, www.error); + www.Dispose(); + www = null; + } + if (www == null) + { + ExecuteNextBatch(); + } + return mJobState; + } + + public void ProcessResult(byte[] bytes, string errorMsg) + { + if (string.IsNullOrEmpty(errorMsg)) + { + string @string = Encoding.UTF8.GetString(bytes, 0, bytes.Length); + Debug.Log(ParseTranslationResult(@string, "aab")); + if (string.IsNullOrEmpty(errorMsg)) + { + if (_OnTranslationReady != null) + { + _OnTranslationReady(_requests, null); + } + return; + } + } + mJobState = eJobState.Failed; + mErrorMessage = errorMsg; + } + + private string ParseTranslationResult(string html, string OriginalText) + { + try + { + int num = html.IndexOf("TRANSLATED_TEXT='", StringComparison.Ordinal) + "TRANSLATED_TEXT='".Length; + int num2 = html.IndexOf("';var", num, StringComparison.Ordinal); + string input = html.Substring(num, num2 - num); + input = Regex.Replace(input, "\\\\x([a-fA-F0-9]{2})", (Match match) => char.ConvertFromUtf32(int.Parse(match.Groups[1].Value, NumberStyles.HexNumber))); + input = Regex.Replace(input, "&#(\\d+);", (Match match) => char.ConvertFromUtf32(int.Parse(match.Groups[1].Value))); + input = input.Replace("<br>", "\n"); + if (OriginalText.ToUpper() == OriginalText) + { + input = input.ToUpper(); + } + else if (GoogleTranslation.UppercaseFirst(OriginalText) == OriginalText) + { + input = GoogleTranslation.UppercaseFirst(input); + } + else if (GoogleTranslation.TitleCase(OriginalText) == OriginalText) + { + input = GoogleTranslation.TitleCase(input); + } + return input; + } + catch (Exception ex) + { + Debug.LogError(ex.Message); + return string.Empty; + } + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_WWW.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_WWW.cs new file mode 100644 index 0000000..f10586e --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationJob_WWW.cs @@ -0,0 +1,17 @@ +using UnityEngine.Networking; + +namespace I2.Loc; + +public class TranslationJob_WWW : TranslationJob +{ + public UnityWebRequest www; + + public override void Dispose() + { + if (www != null) + { + www.Dispose(); + } + www = null; + } +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/TranslationQuery.cs b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationQuery.cs new file mode 100644 index 0000000..009b151 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/TranslationQuery.cs @@ -0,0 +1,16 @@ +namespace I2.Loc; + +public struct TranslationQuery +{ + public string OrigText; + + public string Text; + + public string LanguageCode; + + public string[] TargetLanguagesCode; + + public string[] Results; + + public string[] Tags; +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/eLanguageDataFlags.cs b/Thronefall_v1.57/Thronefall/I2.Loc/eLanguageDataFlags.cs new file mode 100644 index 0000000..4378a2d --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/eLanguageDataFlags.cs @@ -0,0 +1,8 @@ +namespace I2.Loc; + +public enum eLanguageDataFlags +{ + DISABLED = 1, + KEEP_LOADED = 2, + NOT_LOADED = 4 +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/ePluralType.cs b/Thronefall_v1.57/Thronefall/I2.Loc/ePluralType.cs new file mode 100644 index 0000000..cffad52 --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/ePluralType.cs @@ -0,0 +1,11 @@ +namespace I2.Loc; + +public enum ePluralType +{ + Zero, + One, + Two, + Few, + Many, + Plural +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/eSpreadsheetUpdateMode.cs b/Thronefall_v1.57/Thronefall/I2.Loc/eSpreadsheetUpdateMode.cs new file mode 100644 index 0000000..75d6fca --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/eSpreadsheetUpdateMode.cs @@ -0,0 +1,9 @@ +namespace I2.Loc; + +public enum eSpreadsheetUpdateMode +{ + None, + Replace, + Merge, + AddNewTerms +} diff --git a/Thronefall_v1.57/Thronefall/I2.Loc/eTermType.cs b/Thronefall_v1.57/Thronefall/I2.Loc/eTermType.cs new file mode 100644 index 0000000..dd00f6d --- /dev/null +++ b/Thronefall_v1.57/Thronefall/I2.Loc/eTermType.cs @@ -0,0 +1,17 @@ +namespace I2.Loc; + +public enum eTermType +{ + Text, + Font, + Texture, + AudioClip, + GameObject, + Sprite, + Material, + Child, + Mesh, + TextMeshPFont, + Object, + Video +} |