315 lines
12 KiB
C#
315 lines
12 KiB
C#
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<string, List<GoogleTranslate>> _cacheTranslate = new Dictionary<string, List<GoogleTranslate>>(128);
|
|
//缓存聊天翻译的引用计数
|
|
private Dictionary<string, int> _cacheRefrence = new Dictionary<string, int>();
|
|
//错误列表
|
|
private List<string> _errorList = new List<string>();
|
|
#endregion
|
|
|
|
#region//const
|
|
private const string API_KEY = "AIzaSyDHnb3jqNWPQ1fSAtgsFamwmZTlEzTq2Fs";
|
|
#endregion
|
|
|
|
public void TransLate(string time, string source, string target, string text, MyAction<string, GoogleTranslateCode> action)
|
|
{
|
|
if (string.IsNullOrEmpty(text))
|
|
return;
|
|
string cacheStr = string.Empty;
|
|
List<string> cacheList = new List<string>();
|
|
List<GoogleTranslate> translateList = new List<GoogleTranslate>();
|
|
int start = 0;
|
|
int end = text.LastIndexOf("</t>");
|
|
int orStart = start;
|
|
int lastEnd = end;
|
|
while (start < lastEnd)
|
|
{
|
|
start = text.IndexOf("<t=0>", start);
|
|
if (start == -1)
|
|
break;
|
|
start += 4;
|
|
end = text.IndexOf("</t>", 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<GoogleTranslate> translates, MyAction<List<GoogleTranslate>, GoogleTranslateCode> action)
|
|
{
|
|
if (translates == null || translates.Count == 0)
|
|
return;
|
|
|
|
List<GoogleTranslate> 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<List<GoogleTranslate>, 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<GoogleTranslate> 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<string> keys = new List<string>(_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>();
|
|
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,
|
|
}
|
|
}
|
|
|