Files
Main/Assets/Code/Logic/GoogleTranslate/GoogleTranslateSystem.cs

315 lines
12 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
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,
}
}