using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Net; using System.Text; using Thousandto.Core.Base; using UnityEngine; using UnityEngine.Gonbest.MagicCube; namespace Thousandto.Code.Logic { //google翻译 public class GoogleTranslateSystem { #region//私有变量 //缓存聊天翻译 最多缓存128条翻译 private Dictionary> _cacheTranslate = new Dictionary>(128); //缓存聊天翻译的引用计数 private Dictionary _cacheRefrence = new Dictionary(); //错误列表 private List _errorList = new List(); #endregion #region//const private const string API_KEY = "AIzaSyDHnb3jqNWPQ1fSAtgsFamwmZTlEzTq2Fs"; #endregion public void TransLate(string time, string source, string target, string text, MyAction action) { if (string.IsNullOrEmpty(text)) return; string cacheStr = string.Empty; List cacheList = new List(); List translateList = new List(); int start = 0; int end = text.LastIndexOf(""); int orStart = start; int lastEnd = end; while (start < lastEnd) { start = text.IndexOf("", start); if (start == -1) break; start += 4; end = text.IndexOf("", start); string ss = text.Substring(start); if (start >= end || end == -1) break; int index = start; for (int i = start; i < end; i++) { int findPos = text.IndexOf(',', i); if (findPos < end && findPos != -1) { index = findPos; } else { break; } } start = index + 1; string translate = text.Substring(start, end - start); GoogleTranslate data = new GoogleTranslate(); data.text = translate; data.index = translateList.Count; translateList.Add(data); cacheStr = text.Substring(orStart, start - orStart); cacheList.Add(cacheStr); orStart = end; start = end + 3; } cacheStr = text.Substring(end); cacheList.Add(cacheStr); TransLate(time, source, target, translateList, (translates, code) => { if (code == GoogleTranslateCode.Success) { //翻译成功了 重新组装翻译后的文字 if (translates == null || translates.Count == 0) { //翻译失败 action(string.Empty, GoogleTranslateCode.Error); } else { if (translates.Count != cacheList.Count - 1) { //翻译后语句数量和原文不匹配 action(string.Empty, GoogleTranslateCode.Error); } else { StringBuilder sb = new StringBuilder(); for (int m = 0; m < cacheList.Count; m++) { string des = string.Empty; if (m < cacheList.Count - 1) { string translate = string.Empty; for (int n = 0; n < translates.Count; n++) { if (translates[n].index == m) { translate = translates[n].text; break; } } des = string.Format("{0}{1}", cacheList[m], translate); } else { des = cacheList[m]; } sb.Append(des); } action(sb.ToString(), GoogleTranslateCode.Success); } } } else { //翻译失败 action(string.Empty, code); } _cacheRefrence.Remove(time); }); } //翻译 private void TransLate(string time, string source, string target, List translates, MyAction, GoogleTranslateCode> action) { if (translates == null || translates.Count == 0) return; List list = null; if (_cacheTranslate.ContainsKey(time)) { list = _cacheTranslate[time]; } if (list == null) { //没有找到翻译 _cacheRefrence[time] = translates.Count; //逐条翻译 for (int i = 0; i < translates.Count; i++) { if (_errorList.Contains(time)) { _errorList.Remove(time); break; } else { CoroutinePool.AddTask(DoTrans(time, source, target, translates[i], action)); } } } else { //直接返回翻译的列表 action(list, GoogleTranslateCode.Success); } } private IEnumerator DoTrans(string time, string sourceLang, string targetLang, GoogleTranslate sourceData, MyAction, GoogleTranslateCode> action) { if (sourceData != null) { string url = "https://translation.googleapis.com/language/translate/v2?key=" + API_KEY + "&target=" + targetLang; url += "&source=" + sourceLang; url += "&q=" + Uri.EscapeUriString(sourceData.text); WWW www = new WWW(url); float outTime = 1000; float requstTime = Time.time; yield return www; if (www.isDone) { if (string.IsNullOrEmpty(www.error)) { string translatedText = string.Empty; var node = SimpleJson.JSONNode.Parse(www.text); if (node["data"] != null) { SimpleJson.JSONArray array = node["data"]["translations"].AsArray; for (int i = 0; i < array.Count; i++) { translatedText = array[i]["translatedText"]; break; } } var N = SimpleJson.JSONNode.Parse(www.text); string indexStr = translatedText.Substring(translatedText.Length - 1); List translateList = null; if (_cacheTranslate.ContainsKey(time)) { translateList = _cacheTranslate[time]; GoogleTranslate data = new GoogleTranslate(); data.text = translatedText; data.index = sourceData.index; translateList.Add(data); } else { if (_cacheTranslate.Count > 127) { List keys = new List(_cacheTranslate.Count); //移除第一条数据 var enumer = _cacheTranslate.GetEnumerator(); try { while (enumer.MoveNext()) { keys.Add(enumer.Current.Key); break; } } finally { enumer.Dispose(); } keys.Sort((a, b) => { return a.CompareTo(b); }); for (int k = 0; k < keys.Count; k++) { UnityEngine.Debug.LogError(keys[k]); } _cacheTranslate.Remove(keys[0]); } translateList = new List(); GoogleTranslate data = new GoogleTranslate(); data.text = translatedText; data.index = sourceData.index; translateList.Add(data); _cacheTranslate[time] = translateList; } if (!_cacheRefrence.ContainsKey(time)) { UnityEngine.Debug.LogError("翻译出错!"); _cacheTranslate.Remove(time); _cacheRefrence.Remove(time); _errorList.Add(time); } else { _cacheRefrence[time] -= 1; if (_cacheRefrence[time] == 0) { action(_cacheTranslate[time], GoogleTranslateCode.Success); } } } } else { if (Time.time - requstTime >= outTime) { //请求超时 _cacheTranslate.Remove(time); _cacheRefrence.Remove(time); _errorList.Add(time); action(null, GoogleTranslateCode.TimeOut); } } try { //HttpWebRequest www = (HttpWebRequest)WebRequest.Create(url);//new WWW(url); //www.Method = "POST"; //www.Timeout = 1000; //HttpWebResponse httpWebResponse = (HttpWebResponse)www.GetResponse(); //StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()); //string content = streamReader.ReadToEnd(); //var N = SimpleJSON.JSONNode.Parse(content); //string translatedText = N[0][0][0]; //httpWebResponse.Close(); //streamReader.Close(); } catch { //UnityEngine.Debug.LogError("翻译超时!"); //_cacheTranslate.Remove(time); //_cacheRefrence.Remove(time); //action(null, GoogleTranslateCode.TimeOut); } } } } public class GoogleTranslate { public string text = string.Empty; public int index = 0; } public enum GoogleTranslateCode { Success = 0, TimeOut = 1, Error = 2, } }