Core/Chat: Chat translation improvements (needs testing unsure)

Port From (https://github.com/TrinityCore/TrinityCore/commit/67e16888ac76d144fab7433b542d660b13e7cb62)
This commit is contained in:
hondacrx
2021-05-04 10:45:19 -04:00
parent cbb22d291e
commit c665330843
4 changed files with 173 additions and 42 deletions
+30
View File
@@ -225,6 +225,36 @@ namespace System
return Encoding.UTF8.GetByteCount(str);
}
public static bool isExtendedLatinCharacter(char wchar)
{
if (isBasicLatinCharacter(wchar))
return true;
if (wchar >= 0x00C0 && wchar <= 0x00D6) // LATIN CAPITAL LETTER A WITH GRAVE - LATIN CAPITAL LETTER O WITH DIAERESIS
return true;
if (wchar >= 0x00D8 && wchar <= 0x00DE) // LATIN CAPITAL LETTER O WITH STROKE - LATIN CAPITAL LETTER THORN
return true;
if (wchar == 0x00DF) // LATIN SMALL LETTER SHARP S
return true;
if (wchar >= 0x00E0 && wchar <= 0x00F6) // LATIN SMALL LETTER A WITH GRAVE - LATIN SMALL LETTER O WITH DIAERESIS
return true;
if (wchar >= 0x00F8 && wchar <= 0x00FE) // LATIN SMALL LETTER O WITH STROKE - LATIN SMALL LETTER THORN
return true;
if (wchar >= 0x0100 && wchar <= 0x012F) // LATIN CAPITAL LETTER A WITH MACRON - LATIN SMALL LETTER I WITH OGONEK
return true;
if (wchar == 0x1E9E) // LATIN CAPITAL LETTER SHARP S
return true;
return false;
}
public static bool isBasicLatinCharacter(char wchar)
{
if (wchar >= 'a' && wchar <= 'z') // LATIN SMALL LETTER A - LATIN SMALL LETTER Z
return true;
if (wchar >= 'A' && wchar <= 'Z') // LATIN CAPITAL LETTER A - LATIN CAPITAL LETTER Z
return true;
return false;
}
#endregion
#region BinaryReader
+138 -38
View File
@@ -103,37 +103,155 @@ namespace Game.Chat
return _wordsMap.LookupByKey(Tuple.Create(language, wordLen));
}
public string Translate(string msg, uint sourcePlayerLanguage)
public string Translate(string msg, uint language, Locale locale)
{
StringBuilder result = new StringBuilder();
StringArray tokens = new(msg, ' ');
string textToTranslate = "";
StripHyperlinks(msg, ref textToTranslate);
ReplaceUntranslatableCharactersWithSpace(ref textToTranslate);
bool first = true;
string result = "";
StringArray tokens = new(textToTranslate, ' ');
foreach (string str in tokens)
{
string nextPart = str;
uint wordLen = (uint)Math.Min(18U, str.Length);
var wordGroup = FindWordGroup(sourcePlayerLanguage, wordLen);
if (wordGroup.Empty())
nextPart = "";
else
uint wordLen = (uint)Math.Min(18, str.Length);
var wordGroup = FindWordGroup(language, wordLen);
if (!wordGroup.Empty())
{
uint wordHash = SStrHash(str, true);
byte idxInsideGroup = (byte)(wordHash % wordGroup.Count);
nextPart = wordGroup[idxInsideGroup];
byte idxInsideGroup = (byte)(wordHash % wordGroup.Count());
string replacementWord = wordGroup[idxInsideGroup];
switch (locale)
{
case Locale.koKR:
case Locale.zhCN:
case Locale.zhTW:
{
int length = Math.Min(str.Length, replacementWord.Length);
for (int i = 0; i < length; ++i)
{
if (str[i] >= 'A' && str[i] <= 'Z')
result += char.ToUpper(replacementWord[i]);
else
result += replacementWord[i];
}
break;
}
default:
{
int length = Math.Min(str.Length, replacementWord.Length);
for (int i = 0; i < length; ++i)
{
if (char.IsUpper(str[i]))
result += char.ToUpper(replacementWord[i]);
else
result += char.ToLower(replacementWord[i]);
}
break;
}
}
}
if (first)
first = false;
else
result.Append(" ");
result.Append(nextPart);
result += ' ';
}
return result.ToString();
if (!result.IsEmpty())
result.Remove(result.Length - 1);
return result;
}
static char upper_backslash(char c) { return c == '/' ? '\\' : char.ToUpper(c); }
public bool IsLanguageExist(Language languageId)
{
return CliDB.LanguagesStorage.HasRecord((uint)languageId);
}
public List<LanguageDesc> GetLanguageDescById(Language languageId)
{
return _langsMap.LookupByKey((uint)languageId);
}
public bool ForEachLanguage(Func<uint, LanguageDesc, bool> callback)
{
foreach (var pair in _langsMap)
if (!callback(pair.Key, pair.Value))
return false;
return true;
}
void StripHyperlinks(string source, ref string dest)
{
char[] destChar = new char[source.Length];
int destSize = 0;
bool skipSquareBrackets = false;
for (int i = 0; i < source.Length; ++i)
{
char c = source[i];
if (c != '|')
{
if (!skipSquareBrackets || (c != '[' && c != ']'))
destChar[destSize++] = source[i];
continue;
}
if (i + 1 >= source.Length)
break;
switch (source[i + 1])
{
case 'c':
case 'C':
// skip color
i += 9;
break;
case 'r':
++i;
break;
case 'H':
// skip just past first |h
i = source.IndexOf("|h", i);
if (i != -1)
i += 2;
skipSquareBrackets = true;
break;
case 'h':
++i;
skipSquareBrackets = false;
break;
case 'T':
// skip just past closing |t
i = source.IndexOf("|t", i);
if (i != -1)
i += 2;
break;
default:
break;
}
}
dest = new string(destChar, 0, destSize);
}
void ReplaceUntranslatableCharactersWithSpace(ref string text)
{
var chars = text.ToCharArray();
for (var i = 0; i < text.Length; ++i)
{
var w = chars[i];
if (!Extensions.isExtendedLatinCharacter(w) && !char.IsNumber(w) && w <= 0xFF && w != '\\')
chars[i] = ' ';
}
text = new string(chars);
}
static char upper_backslash(char c)
{
return c == '/' ? '\\' : char.ToUpper(c);
}
static uint[] s_hashtable =
{
@@ -158,23 +276,5 @@ namespace Game.Chat
return seed != 0 ? seed : 1;
}
public bool IsLanguageExist(Language languageId)
{
return CliDB.LanguagesStorage.HasRecord((uint)languageId);
}
public List<LanguageDesc> GetLanguageDescById(Language languageId)
{
return _langsMap.LookupByKey((uint)languageId);
}
public bool ForEachLanguage(Func<uint, LanguageDesc, bool> callback)
{
foreach (var pair in _langsMap)
if (!callback(pair.Key, pair.Value))
return false;
return true;
}
}
}
+4 -3
View File
@@ -6233,13 +6233,14 @@ namespace Game.Entities
void SendChatMessageToSetInRange(ChatMsg chatMsg, Language language, string text, float range)
{
ChatPacketSender sender = new(chatMsg, language, this, this, text);
CustomChatTextBuilder builder = new(this, chatMsg, text, language, this);
LocalizedDo localizer = new(builder);
// Send to self
sender.Invoke(this);
localizer.Invoke(this);
// Send to players
MessageDistDeliverer<ChatPacketSender> notifier = new(this, sender, range);
MessageDistDeliverer<LocalizedDo> notifier = new(this, localizer, range);
Cell.VisitWorldObjects(this, notifier, range);
}
+1 -1
View File
@@ -69,7 +69,7 @@ namespace Game.Chat
if (!TranslatedPacket.HasValue)
{
TranslatedPacket.HasValue = true;
TranslatedPacket.Value.Initialize(Type, Language, Sender, Receiver, Global.LanguageMgr.Translate(Text, (uint)Language), AchievementId, "", Locale);
TranslatedPacket.Value.Initialize(Type, Language, Sender, Receiver, Global.LanguageMgr.Translate(Text, (uint)Language, player.GetSession().GetSessionDbcLocale()), AchievementId, "", Locale);
TranslatedPacket.Value.Write();
}