Core/Chat: Chat translation improvements (needs testing unsure)
Port From (https://github.com/TrinityCore/TrinityCore/commit/67e16888ac76d144fab7433b542d660b13e7cb62)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user