using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Text.RegularExpressions; using UnityEngine; namespace I2.Loc { public static class GoogleTranslation { public static bool CanTranslate() { return LocalizationManager.Sources.Count > 0 && !string.IsNullOrEmpty(LocalizationManager.GetWebServiceURL(null)); } public static void Translate(string text, string LanguageCodeFrom, string LanguageCodeTo, Action OnTranslationReady) { LocalizationManager.InitializeIfNeeded(); if (!GoogleTranslation.CanTranslate()) { OnTranslationReady(null, "WebService is not set correctly or needs to be reinstalled"); return; } if (LanguageCodeTo == LanguageCodeFrom) { OnTranslationReady(text, null); return; } Dictionary queries = new Dictionary(); if (string.IsNullOrEmpty(LanguageCodeTo)) { OnTranslationReady(string.Empty, null); return; } GoogleTranslation.CreateQueries(text, LanguageCodeFrom, LanguageCodeTo, queries); GoogleTranslation.Translate(queries, delegate(Dictionary results, string error) { if (!string.IsNullOrEmpty(error) || results.Count == 0) { OnTranslationReady(null, error); return; } string arg = GoogleTranslation.RebuildTranslation(text, queries, LanguageCodeTo); OnTranslationReady(arg, null); }, true); } public static string ForceTranslate(string text, string LanguageCodeFrom, string LanguageCodeTo) { Dictionary dictionary = new Dictionary(); GoogleTranslation.AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dictionary); TranslationJob_Main translationJob_Main = new TranslationJob_Main(dictionary, null); TranslationJob.eJobState state; do { state = translationJob_Main.GetState(); } while (state == TranslationJob.eJobState.Running); if (state == TranslationJob.eJobState.Failed) { return null; } return GoogleTranslation.GetQueryResult(text, string.Empty, dictionary); } public static void Translate(Dictionary requests, Action, string> OnTranslationReady, bool usePOST = true) { GoogleTranslation.AddTranslationJob(new TranslationJob_Main(requests, OnTranslationReady)); } public static bool ForceTranslate(Dictionary requests, bool usePOST = true) { TranslationJob_Main translationJob_Main = new TranslationJob_Main(requests, null); TranslationJob.eJobState state; do { state = translationJob_Main.GetState(); } while (state == TranslationJob.eJobState.Running); return state != TranslationJob.eJobState.Failed; } public static List ConvertTranslationRequest(Dictionary requests, bool encodeGET) { List list = new List(); StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair keyValuePair in requests) { TranslationQuery value = keyValuePair.Value; if (stringBuilder.Length > 0) { stringBuilder.Append(""); } 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 = (!(GoogleTranslation.TitleCase(value.Text) == value.Text)) ? value.Text : value.Text.ToLowerInvariant(); if (!encodeGET) { stringBuilder.Append(text); } else { 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) { GoogleTranslation.mTranslationJobs.Add(job); if (GoogleTranslation.mTranslationJobs.Count == 1) { CoroutineManager.Start(GoogleTranslation.WaitForTranslations()); } } private static IEnumerator WaitForTranslations() { while (GoogleTranslation.mTranslationJobs.Count > 0) { TranslationJob[] jobs = GoogleTranslation.mTranslationJobs.ToArray(); foreach (TranslationJob translationJob in jobs) { if (translationJob.GetState() != TranslationJob.eJobState.Running) { GoogleTranslation.mTranslationJobs.Remove(translationJob); } } yield return null; } yield break; } public static string ParseTranslationResult(string html, Dictionary requests) { if (!html.StartsWith("") && !html.StartsWith("")) { string[] array = html.Split(new string[] { "" }, StringSplitOptions.None); string[] separator = new string[] { "" }; int num = 0; string[] array2 = requests.Keys.ToArray(); foreach (string text in array2) { TranslationQuery value = GoogleTranslation.FindQueryFromOrigText(text, requests); string text2 = array[num++]; if (value.Tags != null) { int j = 0; int num2 = value.Tags.Length; while (j < num2) { text2 = text2.Replace(((char)(9728 + j)).ToString(), value.Tags[j]); j++; } } value.Results = text2.Split(separator, StringSplitOptions.None); if (GoogleTranslation.TitleCase(text) == text) { for (int k = 0; k < value.Results.Length; k++) { value.Results[k] = GoogleTranslation.TitleCase(value.Results[k]); } } requests[value.OrigText] = value; } return null; } 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 string.Empty; } return "There was a problem contacting the WebService. Please try again later\n" + html; } public static bool IsTranslating() { return GoogleTranslation.mCurrentTranslations.Count > 0 || GoogleTranslation.mTranslationJobs.Count > 0; } public static void CancelCurrentGoogleTranslations() { GoogleTranslation.mCurrentTranslations.Clear(); foreach (TranslationJob translationJob in GoogleTranslation.mTranslationJobs) { translationJob.Dispose(); } GoogleTranslation.mTranslationJobs.Clear(); } public static void CreateQueries(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary dict) { if (!text.Contains("[i2s_")) { GoogleTranslation.CreateQueries_Plurals(text, LanguageCodeFrom, LanguageCodeTo, dict); return; } Dictionary specializations = SpecializationManager.GetSpecializations(text, null); foreach (KeyValuePair keyValuePair in specializations) { GoogleTranslation.CreateQueries_Plurals(keyValuePair.Value, LanguageCodeFrom, LanguageCodeTo, dict); } } private static void CreateQueries_Plurals(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary dict) { bool flag = text.Contains("{[#"); bool flag2 = text.Contains("[i2p_"); if (!GoogleTranslation.HasParameters(text) || (!flag && !flag2)) { GoogleTranslation.AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dict); return; } bool forceTag = flag; for (ePluralType ePluralType = ePluralType.Zero; ePluralType <= ePluralType.Plural; ePluralType++) { string pluralType = ePluralType.ToString(); if (GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, pluralType)) { string text2 = GoogleTranslation.GetPluralText(text, pluralType); int pluralTestNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, ePluralType); string pluralParameter = GoogleTranslation.GetPluralParameter(text2, forceTag); if (!string.IsNullOrEmpty(pluralParameter)) { text2 = text2.Replace(pluralParameter, pluralTestNumber.ToString()); } GoogleTranslation.AddQuery(text2, LanguageCodeFrom, LanguageCodeTo, dict); } } } public static void AddQuery(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary dict) { if (string.IsNullOrEmpty(text)) { return; } if (!dict.ContainsKey(text)) { TranslationQuery value = new TranslationQuery { OrigText = text, LanguageCode = LanguageCodeFrom, TargetLanguagesCode = new string[] { LanguageCodeTo } }; value.Text = text; GoogleTranslation.ParseNonTranslatableElements(ref value); dict[text] = value; } else { TranslationQuery value2 = dict[text]; if (Array.IndexOf(value2.TargetLanguagesCode, LanguageCodeTo) < 0) { value2.TargetLanguagesCode = value2.TargetLanguagesCode.Concat(new string[] { LanguageCodeTo }).Distinct().ToArray(); } dict[text] = value2; } } private static string GetTranslation(string text, string LanguageCodeTo, Dictionary dict) { if (!dict.ContainsKey(text)) { return null; } TranslationQuery translationQuery = dict[text]; int num = Array.IndexOf(translationQuery.TargetLanguagesCode, LanguageCodeTo); if (num < 0) { return string.Empty; } if (translationQuery.Results == null) { return string.Empty; } return translationQuery.Results[num]; } private static TranslationQuery FindQueryFromOrigText(string origText, Dictionary dict) { foreach (KeyValuePair keyValuePair in dict) { if (keyValuePair.Value.OrigText == origText) { return keyValuePair.Value; } } return default(TranslationQuery); } public static bool HasParameters(string text) { int num = text.IndexOf("{["); return num >= 0 && text.IndexOf("]}", num) > 0; } public static string GetPluralParameter(string text, bool forceTag) { int num = text.IndexOf("{[#"); if (num < 0) { if (forceTag) { return null; } num = text.IndexOf("{["); } if (num < 0) { return null; } int num2 = text.IndexOf("]}", num + 2); 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); if (num >= 0) { num += pluralType.Length; int num2 = text.IndexOf("[i2p_", num); if (num2 < 0) { num2 = text.Length; } return text.Substring(num, num2 - num); } num = text.IndexOf("[i2p_"); if (num < 0) { return text; } if (num > 0) { return text.Substring(0, num); } num = text.IndexOf("]"); if (num < 0) { return text; } num++; int num3 = text.IndexOf("[i2p_", num); 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; int count = matches.Count; while (i < count) { string captureMatch = GoogleTranslation.GetCaptureMatch(matches[i]); if (captureMatch[0] == '/' && tag.StartsWith(captureMatch.Substring(1))) { return i; } i++; } return -1; } private static string GetCaptureMatch(Match match) { for (int i = match.Groups.Count - 1; i >= 0; i--) { if (match.Groups[i].Success) { return match.Groups[i].ToString(); } } return match.ToString(); } 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 list = new List(); int i = 0; int count = matchCollection.Count; while (i < count) { string captureMatch = GoogleTranslation.GetCaptureMatch(matchCollection[i]); int num = GoogleTranslation.FindClosingTag(captureMatch, matchCollection, i); if (num < 0) { string text2 = matchCollection[i].ToString(); if (text2.StartsWith("{[") && text2.EndsWith("]}")) { text = text.Replace(text2, ((char)(9728 + list.Count)).ToString()); 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, ((char)(9728 + list.Count)).ToString()); list.Add(text3); } else { string text4 = matchCollection[i].ToString(); text = text.Replace(text4, ((char)(9728 + list.Count)).ToString()); list.Add(text4); string text5 = matchCollection[num].ToString(); text = text.Replace(text5, ((char)(9728 + list.Count)).ToString()); list.Add(text5); } i++; } query.Text = text; query.Tags = list.ToArray(); } public static string GetQueryResult(string text, string LanguageCodeTo, Dictionary 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 dict, string LanguageCodeTo) { if (!text.Contains("[i2s_")) { return GoogleTranslation.RebuildTranslation_Plural(text, dict, LanguageCodeTo); } Dictionary specializations = SpecializationManager.GetSpecializations(text, null); Dictionary dictionary = new Dictionary(); foreach (KeyValuePair keyValuePair in specializations) { dictionary[keyValuePair.Key] = GoogleTranslation.RebuildTranslation_Plural(keyValuePair.Value, dict, LanguageCodeTo); } return SpecializationManager.SetSpecializedText(dictionary); } private static string RebuildTranslation_Plural(string text, Dictionary dict, string LanguageCodeTo) { bool flag = text.Contains("{[#"); bool flag2 = text.Contains("[i2p_"); if (!GoogleTranslation.HasParameters(text) || (!flag && !flag2)) { return GoogleTranslation.GetTranslation(text, LanguageCodeTo, dict); } StringBuilder stringBuilder = new StringBuilder(); string b = null; bool forceTag = flag; for (ePluralType ePluralType = ePluralType.Plural; ePluralType >= ePluralType.Zero; ePluralType--) { string text2 = ePluralType.ToString(); if (GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, text2)) { string text3 = GoogleTranslation.GetPluralText(text, text2); int pluralTestNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, ePluralType); string pluralParameter = GoogleTranslation.GetPluralParameter(text3, forceTag); if (!string.IsNullOrEmpty(pluralParameter)) { text3 = text3.Replace(pluralParameter, pluralTestNumber.ToString()); } string text4 = GoogleTranslation.GetTranslation(text3, LanguageCodeTo, dict); if (!string.IsNullOrEmpty(pluralParameter)) { text4 = text4.Replace(pluralTestNumber.ToString(), pluralParameter); } if (ePluralType == ePluralType.Plural) { b = text4; } else { if (text4 == b) { goto IL_117; } stringBuilder.AppendFormat("[i2p_{0}]", text2); } stringBuilder.Append(text4); } IL_117:; } 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); } private static List mCurrentTranslations = new List(); private static List mTranslationJobs = new List(); } }