mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
6fbb2cbaa3
4 files changed
+553
-8
No files matched your search
@@ -0,0 +1,478 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ArabicSupport
|
||||
{
|
||||
public class ArabicFixer
|
||||
{
|
||||
public static string Fix(string str)
|
||||
{
|
||||
return Fix(str, false, true);
|
||||
}
|
||||
|
||||
public static string Fix(string str, bool rtl)
|
||||
{
|
||||
if (rtl)
|
||||
{
|
||||
return Fix(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] words = str.Split(' ');
|
||||
string result = "";
|
||||
string arabicToIgnore = "";
|
||||
foreach (string word in words)
|
||||
{
|
||||
if (word.Length > 0 && char.IsLower(word.ToLower()[word.Length / 2]))
|
||||
{
|
||||
result += Fix(arabicToIgnore) + word + " ";
|
||||
arabicToIgnore = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
arabicToIgnore += word + " ";
|
||||
}
|
||||
}
|
||||
if (arabicToIgnore != "")
|
||||
result += Fix(arabicToIgnore);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Fix(string str, bool showTashkeel, bool useHinduNumbers)
|
||||
{
|
||||
ArabicFixerTool.showTashkeel = showTashkeel;
|
||||
ArabicFixerTool.useHinduNumbers = useHinduNumbers;
|
||||
|
||||
if (str.Contains("\n"))
|
||||
str = str.Replace("\n", Environment.NewLine);
|
||||
|
||||
if (str.Contains(Environment.NewLine))
|
||||
{
|
||||
string[] stringSeparators = new string[] { Environment.NewLine };
|
||||
string[] strSplit = str.Split(stringSeparators, StringSplitOptions.None);
|
||||
if (strSplit.Length <= 1)
|
||||
return ArabicFixerTool.FixLine(str);
|
||||
|
||||
string outputString = ArabicFixerTool.FixLine(strSplit[0]);
|
||||
int iteration = 1;
|
||||
while (iteration < strSplit.Length)
|
||||
{
|
||||
outputString += Environment.NewLine + ArabicFixerTool.FixLine(strSplit[iteration]);
|
||||
iteration++;
|
||||
}
|
||||
return outputString;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ArabicFixerTool.FixLine(str);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Fix(string str, bool showTashkeel, bool combineTashkeel, bool useHinduNumbers)
|
||||
{
|
||||
ArabicFixerTool.combineTashkeel = combineTashkeel;
|
||||
return Fix(str, showTashkeel, useHinduNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
internal enum IsolatedArabicLetters
|
||||
{
|
||||
Hamza = 0xFE80, Alef = 0xFE8D, AlefHamza = 0xFE83, WawHamza = 0xFE85,
|
||||
AlefMaksoor = 0xFE87, AlefMaksora = 0xFBFC, HamzaNabera = 0xFE89,
|
||||
Ba = 0xFE8F, Ta = 0xFE95, Tha2 = 0xFE99, Jeem = 0xFE9D, H7aa = 0xFEA1,
|
||||
Khaa2 = 0xFEA5, Dal = 0xFEA9, Thal = 0xFEAB, Ra2 = 0xFEAD, Zeen = 0xFEAF,
|
||||
Seen = 0xFEB1, Sheen = 0xFEB5, S9a = 0xFEB9, Dha = 0xFEBD, T6a = 0xFEC1,
|
||||
T6ha = 0xFEC5, Ain = 0xFEC9, Gain = 0xFECD, Fa = 0xFED1, Gaf = 0xFED5,
|
||||
Kaf = 0xFED9, Lam = 0xFEDD, Meem = 0xFEE1, Noon = 0xFEE5, Ha = 0xFEE9,
|
||||
Waw = 0xFEED, Ya = 0xFEF1, AlefMad = 0xFE81, TaMarboota = 0xFE93,
|
||||
PersianPe = 0xFB56, PersianChe = 0xFB7A, PersianZe = 0xFB8A,
|
||||
PersianGaf = 0xFB92, PersianGaf2 = 0xFB8E, PersianYeh = 0xFBFC,
|
||||
}
|
||||
|
||||
internal enum GeneralArabicLetters
|
||||
{
|
||||
Hamza = 0x0621, Alef = 0x0627, AlefHamza = 0x0623, WawHamza = 0x0624,
|
||||
AlefMaksoor = 0x0625, AlefMagsora = 0x0649, HamzaNabera = 0x0626,
|
||||
Ba = 0x0628, Ta = 0x062A, Tha2 = 0x062B, Jeem = 0x062C, H7aa = 0x062D,
|
||||
Khaa2 = 0x062E, Dal = 0x062F, Thal = 0x0630, Ra2 = 0x0631, Zeen = 0x0632,
|
||||
Seen = 0x0633, Sheen = 0x0634, S9a = 0x0635, Dha = 0x0636, T6a = 0x0637,
|
||||
T6ha = 0x0638, Ain = 0x0639, Gain = 0x063A, Fa = 0x0641, Gaf = 0x0642,
|
||||
Kaf = 0x0643, Lam = 0x0644, Meem = 0x0645, Noon = 0x0646, Ha = 0x0647,
|
||||
Waw = 0x0648, Ya = 0x064A, AlefMad = 0x0622, TaMarboota = 0x0629,
|
||||
PersianPe = 0x067E, PersianChe = 0x0686, PersianZe = 0x0698,
|
||||
PersianGaf = 0x06AF, PersianGaf2 = 0x06A9, PersianYeh = 0x06CC,
|
||||
}
|
||||
|
||||
internal struct ArabicMapping
|
||||
{
|
||||
public int from;
|
||||
public int to;
|
||||
public ArabicMapping(int from, int to) { this.from = from; this.to = to; }
|
||||
}
|
||||
|
||||
internal class ArabicTable
|
||||
{
|
||||
private static ArabicMapping[] mapList;
|
||||
private static ArabicTable arabicMapper;
|
||||
|
||||
private ArabicTable()
|
||||
{
|
||||
mapList = new[] {
|
||||
new ArabicMapping((int)GeneralArabicLetters.Hamza, (int)IsolatedArabicLetters.Hamza),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Alef, (int)IsolatedArabicLetters.Alef),
|
||||
new ArabicMapping((int)GeneralArabicLetters.AlefHamza, (int)IsolatedArabicLetters.AlefHamza),
|
||||
new ArabicMapping((int)GeneralArabicLetters.WawHamza, (int)IsolatedArabicLetters.WawHamza),
|
||||
new ArabicMapping((int)GeneralArabicLetters.AlefMaksoor, (int)IsolatedArabicLetters.AlefMaksoor),
|
||||
new ArabicMapping((int)GeneralArabicLetters.AlefMagsora, (int)IsolatedArabicLetters.AlefMaksora),
|
||||
new ArabicMapping((int)GeneralArabicLetters.HamzaNabera, (int)IsolatedArabicLetters.HamzaNabera),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Ba, (int)IsolatedArabicLetters.Ba),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Ta, (int)IsolatedArabicLetters.Ta),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Tha2, (int)IsolatedArabicLetters.Tha2),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Jeem, (int)IsolatedArabicLetters.Jeem),
|
||||
new ArabicMapping((int)GeneralArabicLetters.H7aa, (int)IsolatedArabicLetters.H7aa),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Khaa2, (int)IsolatedArabicLetters.Khaa2),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Dal, (int)IsolatedArabicLetters.Dal),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Thal, (int)IsolatedArabicLetters.Thal),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Ra2, (int)IsolatedArabicLetters.Ra2),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Zeen, (int)IsolatedArabicLetters.Zeen),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Seen, (int)IsolatedArabicLetters.Seen),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Sheen, (int)IsolatedArabicLetters.Sheen),
|
||||
new ArabicMapping((int)GeneralArabicLetters.S9a, (int)IsolatedArabicLetters.S9a),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Dha, (int)IsolatedArabicLetters.Dha),
|
||||
new ArabicMapping((int)GeneralArabicLetters.T6a, (int)IsolatedArabicLetters.T6a),
|
||||
new ArabicMapping((int)GeneralArabicLetters.T6ha, (int)IsolatedArabicLetters.T6ha),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Ain, (int)IsolatedArabicLetters.Ain),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Gain, (int)IsolatedArabicLetters.Gain),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Fa, (int)IsolatedArabicLetters.Fa),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Gaf, (int)IsolatedArabicLetters.Gaf),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Kaf, (int)IsolatedArabicLetters.Kaf),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Lam, (int)IsolatedArabicLetters.Lam),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Meem, (int)IsolatedArabicLetters.Meem),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Noon, (int)IsolatedArabicLetters.Noon),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Ha, (int)IsolatedArabicLetters.Ha),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Waw, (int)IsolatedArabicLetters.Waw),
|
||||
new ArabicMapping((int)GeneralArabicLetters.Ya, (int)IsolatedArabicLetters.Ya),
|
||||
new ArabicMapping((int)GeneralArabicLetters.AlefMad, (int)IsolatedArabicLetters.AlefMad),
|
||||
new ArabicMapping((int)GeneralArabicLetters.TaMarboota, (int)IsolatedArabicLetters.TaMarboota),
|
||||
new ArabicMapping((int)GeneralArabicLetters.PersianPe, (int)IsolatedArabicLetters.PersianPe),
|
||||
new ArabicMapping((int)GeneralArabicLetters.PersianChe, (int)IsolatedArabicLetters.PersianChe),
|
||||
new ArabicMapping((int)GeneralArabicLetters.PersianZe, (int)IsolatedArabicLetters.PersianZe),
|
||||
new ArabicMapping((int)GeneralArabicLetters.PersianGaf, (int)IsolatedArabicLetters.PersianGaf),
|
||||
new ArabicMapping((int)GeneralArabicLetters.PersianGaf2, (int)IsolatedArabicLetters.PersianGaf2),
|
||||
new ArabicMapping((int)GeneralArabicLetters.PersianYeh, (int)IsolatedArabicLetters.PersianYeh)
|
||||
};
|
||||
}
|
||||
|
||||
internal static ArabicTable ArabicMapper
|
||||
{
|
||||
get
|
||||
{
|
||||
if (arabicMapper == null)
|
||||
arabicMapper = new ArabicTable();
|
||||
return arabicMapper;
|
||||
}
|
||||
}
|
||||
|
||||
internal int Convert(int toBeConverted)
|
||||
{
|
||||
for (int i = 0; i < mapList.Length; i++)
|
||||
{
|
||||
var arabicMap = mapList[i];
|
||||
if (arabicMap.from == toBeConverted)
|
||||
return arabicMap.to;
|
||||
}
|
||||
return toBeConverted;
|
||||
}
|
||||
}
|
||||
|
||||
internal class TashkeelLocation
|
||||
{
|
||||
public char tashkeel;
|
||||
public int position;
|
||||
public TashkeelLocation(char tashkeel, int position) { this.tashkeel = tashkeel; this.position = position; }
|
||||
}
|
||||
|
||||
internal class ArabicFixerTool
|
||||
{
|
||||
internal static bool showTashkeel = true;
|
||||
internal static bool combineTashkeel = true;
|
||||
internal static bool useHinduNumbers = false;
|
||||
internal static StringBuilder internalStringBuilder = new StringBuilder();
|
||||
|
||||
internal static void RemoveTashkeel(ref string str, out List<TashkeelLocation> tashkeelLocation)
|
||||
{
|
||||
tashkeelLocation = new List<TashkeelLocation>();
|
||||
var lastSplitIndex = 0;
|
||||
internalStringBuilder.Clear();
|
||||
internalStringBuilder.EnsureCapacity(str.Length);
|
||||
int index = 0;
|
||||
|
||||
void IncrementSB(ref string s, int i)
|
||||
{
|
||||
if (i - lastSplitIndex > 0)
|
||||
internalStringBuilder.Append(s, lastSplitIndex, i - lastSplitIndex);
|
||||
lastSplitIndex = i + 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < str.Length; i++)
|
||||
{
|
||||
if (str[i] == (char)0x064B) { tashkeelLocation.Add(new TashkeelLocation((char)0x064B, i)); index++; IncrementSB(ref str, i); }
|
||||
else if (str[i] == (char)0x064C) { tashkeelLocation.Add(new TashkeelLocation((char)0x064C, i)); index++; IncrementSB(ref str, i); }
|
||||
else if (str[i] == (char)0x064D) { tashkeelLocation.Add(new TashkeelLocation((char)0x064D, i)); index++; IncrementSB(ref str, i); }
|
||||
else if (str[i] == (char)0x064E)
|
||||
{
|
||||
if (index > 0 && combineTashkeel && tashkeelLocation[index - 1].tashkeel == (char)0x0651) { tashkeelLocation[index - 1].tashkeel = (char)0xFC60; IncrementSB(ref str, i); continue; }
|
||||
tashkeelLocation.Add(new TashkeelLocation((char)0x064E, i)); index++; IncrementSB(ref str, i);
|
||||
}
|
||||
else if (str[i] == (char)0x064F)
|
||||
{
|
||||
if (index > 0 && combineTashkeel && tashkeelLocation[index - 1].tashkeel == (char)0x0651) { tashkeelLocation[index - 1].tashkeel = (char)0xFC61; IncrementSB(ref str, i); continue; }
|
||||
tashkeelLocation.Add(new TashkeelLocation((char)0x064F, i)); index++; IncrementSB(ref str, i);
|
||||
}
|
||||
else if (str[i] == (char)0x0650)
|
||||
{
|
||||
if (index > 0 && combineTashkeel && tashkeelLocation[index - 1].tashkeel == (char)0x0651) { tashkeelLocation[index - 1].tashkeel = (char)0xFC62; IncrementSB(ref str, i); continue; }
|
||||
tashkeelLocation.Add(new TashkeelLocation((char)0x0650, i)); index++; IncrementSB(ref str, i);
|
||||
}
|
||||
else if (str[i] == (char)0x0651)
|
||||
{
|
||||
if (index > 0 && combineTashkeel)
|
||||
{
|
||||
if (tashkeelLocation[index - 1].tashkeel == (char)0x064E) { tashkeelLocation[index - 1].tashkeel = (char)0xFC60; IncrementSB(ref str, i); continue; }
|
||||
if (tashkeelLocation[index - 1].tashkeel == (char)0x064F) { tashkeelLocation[index - 1].tashkeel = (char)0xFC61; IncrementSB(ref str, i); continue; }
|
||||
if (tashkeelLocation[index - 1].tashkeel == (char)0x0650) { tashkeelLocation[index - 1].tashkeel = (char)0xFC62; IncrementSB(ref str, i); continue; }
|
||||
}
|
||||
tashkeelLocation.Add(new TashkeelLocation((char)0x0651, i)); index++; IncrementSB(ref str, i);
|
||||
}
|
||||
else if (str[i] == (char)0x0652) { tashkeelLocation.Add(new TashkeelLocation((char)0x0652, i)); index++; IncrementSB(ref str, i); }
|
||||
else if (str[i] == (char)0x0653) { tashkeelLocation.Add(new TashkeelLocation((char)0x0653, i)); index++; IncrementSB(ref str, i); }
|
||||
else if (str[i] == (char)0xFC60) IncrementSB(ref str, i);
|
||||
else if (str[i] == (char)0xFC61) IncrementSB(ref str, i);
|
||||
else if (str[i] == (char)0xFC62) IncrementSB(ref str, i);
|
||||
}
|
||||
|
||||
if (lastSplitIndex != 0)
|
||||
{
|
||||
IncrementSB(ref str, str.Length);
|
||||
str = internalStringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ReturnTashkeel(ref char[] letters, List<TashkeelLocation> tashkeelLocation)
|
||||
{
|
||||
Array.Resize(ref letters, letters.Length + tashkeelLocation.Count);
|
||||
for (int i = 0; i < tashkeelLocation.Count; i++)
|
||||
{
|
||||
var tl = tashkeelLocation[i];
|
||||
for (int j = letters.Length - 1; j > tl.position; j--)
|
||||
letters[j] = letters[j - 1];
|
||||
letters[tl.position] = tl.tashkeel;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string FixLine(string str)
|
||||
{
|
||||
RemoveTashkeel(ref str, out var tashkeelLocation);
|
||||
|
||||
char[] lettersOrigin = new char[str.Length];
|
||||
char[] lettersFinal = str.ToCharArray();
|
||||
|
||||
for (int i = 0; i < lettersOrigin.Length; i++)
|
||||
lettersOrigin[i] = (char)ArabicTable.ArabicMapper.Convert(str[i]);
|
||||
|
||||
for (int i = 0; i < lettersOrigin.Length; i++)
|
||||
{
|
||||
bool skip = false;
|
||||
|
||||
if (lettersOrigin[i] == (char)IsolatedArabicLetters.Lam && i < lettersOrigin.Length - 1)
|
||||
{
|
||||
if (lettersOrigin[i + 1] == (char)IsolatedArabicLetters.AlefMaksoor) { lettersOrigin[i] = (char)0xFEF7; lettersFinal[i + 1] = (char)0xFFFF; skip = true; }
|
||||
else if (lettersOrigin[i + 1] == (char)IsolatedArabicLetters.Alef) { lettersOrigin[i] = (char)0xFEF9; lettersFinal[i + 1] = (char)0xFFFF; skip = true; }
|
||||
else if (lettersOrigin[i + 1] == (char)IsolatedArabicLetters.AlefHamza) { lettersOrigin[i] = (char)0xFEF5; lettersFinal[i + 1] = (char)0xFFFF; skip = true; }
|
||||
else if (lettersOrigin[i + 1] == (char)IsolatedArabicLetters.AlefMad) { lettersOrigin[i] = (char)0xFEF3; lettersFinal[i + 1] = (char)0xFFFF; skip = true; }
|
||||
}
|
||||
|
||||
if (!IsIgnoredCharacter(lettersOrigin[i]))
|
||||
{
|
||||
if (IsMiddleLetter(lettersOrigin, i)) lettersFinal[i] = (char)(lettersOrigin[i] + 3);
|
||||
else if (IsFinishingLetter(lettersOrigin, i)) lettersFinal[i] = (char)(lettersOrigin[i] + 1);
|
||||
else if (IsLeadingLetter(lettersOrigin, i)) lettersFinal[i] = (char)(lettersOrigin[i] + 2);
|
||||
else lettersFinal[i] = lettersOrigin[i];
|
||||
}
|
||||
|
||||
if (skip) i++;
|
||||
|
||||
if (useHinduNumbers)
|
||||
lettersFinal[i] = (char)HandleInduNumber(lettersOrigin[i], lettersFinal[i]);
|
||||
}
|
||||
|
||||
if (showTashkeel && tashkeelLocation.Count > 0)
|
||||
ReturnTashkeel(ref lettersFinal, tashkeelLocation);
|
||||
|
||||
internalStringBuilder.Clear();
|
||||
internalStringBuilder.EnsureCapacity(lettersFinal.Length);
|
||||
|
||||
List<char> numberList = null;
|
||||
void AddNumber(char value) { numberList ??= new List<char>(); numberList.Add(value); }
|
||||
void AppendNumbers()
|
||||
{
|
||||
if (numberList != null && numberList.Count > 0)
|
||||
{
|
||||
for (int j = 0; j < numberList.Count; j++)
|
||||
internalStringBuilder.Append(numberList[numberList.Count - 1 - j]);
|
||||
numberList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = lettersFinal.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (char.IsPunctuation(lettersFinal[i]) && i > 0 && i < lettersFinal.Length - 1 &&
|
||||
(char.IsPunctuation(lettersFinal[i - 1]) || char.IsPunctuation(lettersFinal[i + 1])))
|
||||
{
|
||||
if (lettersFinal[i] == '(') internalStringBuilder.Append(')');
|
||||
else if (lettersFinal[i] == ')') internalStringBuilder.Append('(');
|
||||
else if (lettersFinal[i] == '<') internalStringBuilder.Append('>');
|
||||
else if (lettersFinal[i] == '>') internalStringBuilder.Append('<');
|
||||
else if (lettersFinal[i] == '[') internalStringBuilder.Append(']');
|
||||
else if (lettersFinal[i] == ']') internalStringBuilder.Append('[');
|
||||
else if (lettersFinal[i] != 0xFFFF) internalStringBuilder.Append(lettersFinal[i]);
|
||||
}
|
||||
else if (lettersFinal[i] == ' ' && i > 0 && i < lettersFinal.Length - 1 &&
|
||||
(char.IsLower(lettersFinal[i - 1]) || char.IsUpper(lettersFinal[i - 1]) || char.IsNumber(lettersFinal[i - 1])) &&
|
||||
(char.IsLower(lettersFinal[i + 1]) || char.IsUpper(lettersFinal[i + 1]) || char.IsNumber(lettersFinal[i + 1])))
|
||||
{
|
||||
AddNumber(lettersFinal[i]);
|
||||
}
|
||||
else if (char.IsNumber(lettersFinal[i]) || char.IsLower(lettersFinal[i]) || char.IsUpper(lettersFinal[i]) ||
|
||||
char.IsSymbol(lettersFinal[i]) || char.IsPunctuation(lettersFinal[i]))
|
||||
{
|
||||
if (lettersFinal[i] == '(') AddNumber(')');
|
||||
else if (lettersFinal[i] == ')') AddNumber('(');
|
||||
else if (lettersFinal[i] == '<') AddNumber('>');
|
||||
else if (lettersFinal[i] == '>') AddNumber('<');
|
||||
else if (lettersFinal[i] == '[') internalStringBuilder.Append(']');
|
||||
else if (lettersFinal[i] == ']') internalStringBuilder.Append('[');
|
||||
else AddNumber(lettersFinal[i]);
|
||||
}
|
||||
else if ((lettersFinal[i] >= (char)0xD800 && lettersFinal[i] <= (char)0xDBFF) || (lettersFinal[i] >= (char)0xDC00 && lettersFinal[i] <= (char)0xDFFF))
|
||||
{
|
||||
AddNumber(lettersFinal[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendNumbers();
|
||||
if (lettersFinal[i] != 0xFFFF) internalStringBuilder.Append(lettersFinal[i]);
|
||||
}
|
||||
}
|
||||
AppendNumbers();
|
||||
|
||||
return internalStringBuilder.ToString();
|
||||
}
|
||||
|
||||
internal static ushort HandleInduNumber(ushort letterOrigin, ushort letterFinal)
|
||||
{
|
||||
switch (letterOrigin)
|
||||
{
|
||||
case 0x0030: return 0x0660;
|
||||
case 0x0031: return 0x0661;
|
||||
case 0x0032: return 0x0662;
|
||||
case 0x0033: return 0x0663;
|
||||
case 0x0034: return 0x0664;
|
||||
case 0x0035: return 0x0665;
|
||||
case 0x0036: return 0x0666;
|
||||
case 0x0037: return 0x0667;
|
||||
case 0x0038: return 0x0668;
|
||||
case 0x0039: return 0x0669;
|
||||
default: return letterFinal;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool IsIgnoredCharacter(char ch)
|
||||
{
|
||||
bool isPunctuation = char.IsPunctuation(ch);
|
||||
bool isNumber = char.IsNumber(ch);
|
||||
bool isLower = char.IsLower(ch);
|
||||
bool isUpper = char.IsUpper(ch);
|
||||
bool isSymbol = char.IsSymbol(ch);
|
||||
bool isPersianCharacter = ch == (char)0xFB56 || ch == (char)0xFB7A || ch == (char)0xFB8A || ch == (char)0xFB92 || ch == (char)0xFB8E;
|
||||
bool isPresentationFormB = (ch <= (char)0xFEFF && ch >= (char)0xFE70);
|
||||
bool isAcceptableCharacter = isPresentationFormB || isPersianCharacter || ch == (char)0xFBFC;
|
||||
return isPunctuation || isNumber || isLower || isUpper || isSymbol || !isAcceptableCharacter || ch == 'a' || ch == '>' || ch == '<' || ch == (char)0x061B;
|
||||
}
|
||||
|
||||
internal static bool IsLeadingLetter(char[] letters, int index)
|
||||
{
|
||||
bool lettersThatCannotBeBeforeALeadingLetter = index == 0
|
||||
|| letters[index - 1] == ' ' || letters[index - 1] == '*' || letters[index - 1] == 'A'
|
||||
|| char.IsPunctuation(letters[index - 1]) || letters[index - 1] == '>' || letters[index - 1] == '<'
|
||||
|| letters[index - 1] == (int)IsolatedArabicLetters.Alef || letters[index - 1] == (int)IsolatedArabicLetters.Dal
|
||||
|| letters[index - 1] == (int)IsolatedArabicLetters.Thal || letters[index - 1] == (int)IsolatedArabicLetters.Ra2
|
||||
|| letters[index - 1] == (int)IsolatedArabicLetters.Zeen || letters[index - 1] == (int)IsolatedArabicLetters.PersianZe
|
||||
|| letters[index - 1] == (int)IsolatedArabicLetters.Waw || letters[index - 1] == (int)IsolatedArabicLetters.AlefMad
|
||||
|| letters[index - 1] == (int)IsolatedArabicLetters.AlefHamza || letters[index - 1] == (int)IsolatedArabicLetters.Hamza
|
||||
|| letters[index - 1] == (int)IsolatedArabicLetters.AlefMaksoor || letters[index - 1] == (int)IsolatedArabicLetters.WawHamza;
|
||||
|
||||
bool lettersThatCannotBeALeadingLetter = letters[index] != ' '
|
||||
&& letters[index] != (int)IsolatedArabicLetters.Dal && letters[index] != (int)IsolatedArabicLetters.Thal
|
||||
&& letters[index] != (int)IsolatedArabicLetters.Ra2 && letters[index] != (int)IsolatedArabicLetters.Zeen
|
||||
&& letters[index] != (int)IsolatedArabicLetters.PersianZe && letters[index] != (int)IsolatedArabicLetters.Alef
|
||||
&& letters[index] != (int)IsolatedArabicLetters.AlefHamza && letters[index] != (int)IsolatedArabicLetters.AlefMaksoor
|
||||
&& letters[index] != (int)IsolatedArabicLetters.AlefMad && letters[index] != (int)IsolatedArabicLetters.WawHamza
|
||||
&& letters[index] != (int)IsolatedArabicLetters.Waw && letters[index] != (int)IsolatedArabicLetters.Hamza;
|
||||
|
||||
bool lettersThatCannotBeAfterLeadingLetter = index < letters.Length - 1
|
||||
&& letters[index + 1] != ' ' && letters[index + 1] != '\n' && letters[index + 1] != '\r'
|
||||
&& !char.IsPunctuation(letters[index + 1]) && !char.IsNumber(letters[index + 1])
|
||||
&& !char.IsSymbol(letters[index + 1]) && !char.IsLower(letters[index + 1]) && !char.IsUpper(letters[index + 1])
|
||||
&& letters[index + 1] != (int)IsolatedArabicLetters.Hamza;
|
||||
|
||||
return lettersThatCannotBeBeforeALeadingLetter && lettersThatCannotBeALeadingLetter && lettersThatCannotBeAfterLeadingLetter;
|
||||
}
|
||||
|
||||
internal static bool IsFinishingLetter(char[] letters, int index)
|
||||
{
|
||||
bool lettersThatCannotBeBeforeAFinishingLetter = index != 0 &&
|
||||
letters[index - 1] != ' ' && letters[index - 1] != (int)IsolatedArabicLetters.Dal
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.Thal && letters[index - 1] != (int)IsolatedArabicLetters.Ra2
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.Zeen && letters[index - 1] != (int)IsolatedArabicLetters.PersianZe
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.Waw && letters[index - 1] != (int)IsolatedArabicLetters.Alef
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.AlefMad && letters[index - 1] != (int)IsolatedArabicLetters.AlefHamza
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.AlefMaksoor && letters[index - 1] != (int)IsolatedArabicLetters.WawHamza
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.Hamza && !char.IsPunctuation(letters[index - 1])
|
||||
&& !char.IsSymbol(letters[index - 1]) && letters[index - 1] != '>' && letters[index - 1] != '<';
|
||||
|
||||
bool lettersThatCannotBeFinishingLetters = letters[index] != ' ' && letters[index] != (int)IsolatedArabicLetters.Hamza;
|
||||
|
||||
return lettersThatCannotBeBeforeAFinishingLetter && lettersThatCannotBeFinishingLetters;
|
||||
}
|
||||
|
||||
internal static bool IsMiddleLetter(char[] letters, int index)
|
||||
{
|
||||
bool lettersThatCannotBeMiddleLetters = index != 0 &&
|
||||
letters[index] != (int)IsolatedArabicLetters.Alef && letters[index] != (int)IsolatedArabicLetters.Dal
|
||||
&& letters[index] != (int)IsolatedArabicLetters.Thal && letters[index] != (int)IsolatedArabicLetters.Ra2
|
||||
&& letters[index] != (int)IsolatedArabicLetters.Zeen && letters[index] != (int)IsolatedArabicLetters.PersianZe
|
||||
&& letters[index] != (int)IsolatedArabicLetters.Waw && letters[index] != (int)IsolatedArabicLetters.AlefMad
|
||||
&& letters[index] != (int)IsolatedArabicLetters.AlefHamza && letters[index] != (int)IsolatedArabicLetters.AlefMaksoor
|
||||
&& letters[index] != (int)IsolatedArabicLetters.WawHamza && letters[index] != (int)IsolatedArabicLetters.Hamza;
|
||||
|
||||
bool lettersThatCannotBeBeforeMiddleCharacters = index != 0 &&
|
||||
letters[index - 1] != (int)IsolatedArabicLetters.Alef && letters[index - 1] != (int)IsolatedArabicLetters.Dal
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.Thal && letters[index - 1] != (int)IsolatedArabicLetters.Ra2
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.Zeen && letters[index - 1] != (int)IsolatedArabicLetters.PersianZe
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.Waw && letters[index - 1] != (int)IsolatedArabicLetters.AlefMad
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.AlefHamza && letters[index - 1] != (int)IsolatedArabicLetters.AlefMaksoor
|
||||
&& letters[index - 1] != (int)IsolatedArabicLetters.WawHamza && letters[index - 1] != (int)IsolatedArabicLetters.Hamza
|
||||
&& !char.IsPunctuation(letters[index - 1]) && letters[index - 1] != '>' && letters[index - 1] != '<'
|
||||
&& letters[index - 1] != ' ' && letters[index - 1] != '*';
|
||||
|
||||
bool lettersThatCannotBeAfterMiddleCharacters = index < letters.Length - 1 && letters[index + 1] != ' '
|
||||
&& letters[index + 1] != '\r' && letters[index + 1] != (int)IsolatedArabicLetters.Hamza
|
||||
&& !char.IsNumber(letters[index + 1]) && !char.IsSymbol(letters[index + 1]) && !char.IsPunctuation(letters[index + 1]);
|
||||
|
||||
return lettersThatCannotBeAfterMiddleCharacters && lettersThatCannotBeBeforeMiddleCharacters && lettersThatCannotBeMiddleLetters;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Text;
|
||||
using HarmonyLib;
|
||||
using TMPro;
|
||||
|
||||
namespace ArabicSupport
|
||||
{
|
||||
[HarmonyPatch(typeof(TMP_Text))]
|
||||
public static class ArabicTextPatch
|
||||
{
|
||||
[HarmonyPatch("text", MethodType.Setter)]
|
||||
[HarmonyPrefix]
|
||||
public static void Prefix(TMP_Text __instance, ref string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) return;
|
||||
if (!ContainsArabic(value)) return;
|
||||
|
||||
string wrapped = WrapText(__instance, value);
|
||||
value = ArabicFixer.Fix(wrapped, true);
|
||||
}
|
||||
|
||||
private static bool ContainsArabic(string s)
|
||||
{
|
||||
foreach (char c in s)
|
||||
{
|
||||
if ((c >= '\u0600' && c <= '\u06FF') || (c >= '\uFB50' && c <= '\uFEFF'))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string WrapText(TMP_Text tmp, string text)
|
||||
{
|
||||
if (tmp.rectTransform == null) return text;
|
||||
float maxWidth = tmp.rectTransform.rect.width;
|
||||
if (maxWidth <= 0) return text;
|
||||
|
||||
string[] paragraphs = text.Split('\n');
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (int p = 0; p < paragraphs.Length; p++)
|
||||
{
|
||||
string[] words = paragraphs[p].Split(' ');
|
||||
string line = "";
|
||||
|
||||
foreach (string word in words)
|
||||
{
|
||||
string test = line.Length == 0 ? word : line + " " + word;
|
||||
float width = tmp.GetPreferredValues(test).x;
|
||||
|
||||
if (width > maxWidth && line.Length > 0)
|
||||
{
|
||||
sb.Append(line).Append('\n');
|
||||
line = word;
|
||||
}
|
||||
else
|
||||
line = test;
|
||||
}
|
||||
|
||||
sb.Append(line);
|
||||
if (p < paragraphs.Length - 1) sb.Append('\n');
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,7 @@ gamejewel#8750 | bbb5f1d30 | PatMyBalls | Inappropriate Name |
|
||||
brownapex#1378 | 0926b55a8 | igoonalot | slurs in game |
|
||||
frettedria#8062 | c29fae4c3 | | slurs in game |
|
||||
pluralbug#5217 | cf91054b4 | | slurs in game |
|
||||
oakaverage#9192 | 0aebc840d | Tevell67 | slurs in game |
|
||||
|
||||
## Griefers, Toxic, Harrasing, Racist
|
||||
setmolar#4374 | | 藏族顶针 | Toxic |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Caching]
|
||||
|
||||
## Enable/disable assembly metadata cache
|
||||
## Enable/disable assembly metadata cache
|
||||
## Enabling this will speed up discovery of plugins and patchers by caching the metadata of all types BepInEx discovers.
|
||||
# Setting type: Boolean
|
||||
# Default value: true
|
||||
@@ -16,7 +16,7 @@ DetourProviderType = Default
|
||||
|
||||
[Harmony.Logger]
|
||||
|
||||
## Specifies which Harmony log channels to listen to.
|
||||
## Specifies which Harmony log channels to listen to.
|
||||
## NOTE: IL channel dumps the whole patch methods, use only when needed!
|
||||
# Setting type: LogChannel
|
||||
# Default value: Warn, Error
|
||||
@@ -52,7 +52,7 @@ UnhollowerDeobfuscationRegex =
|
||||
## If enabled, Il2CppInterop will use xref to find dead methods and generate CallerCount attributes.
|
||||
# Setting type: Boolean
|
||||
# Default value: true
|
||||
ScanMethodRefs = false
|
||||
ScanMethodRefs = true
|
||||
|
||||
## If enabled, BepInEx will save dummy assemblies generated by an Cpp2IL dumper into BepInEx/dummy.
|
||||
# Setting type: Boolean
|
||||
@@ -166,27 +166,27 @@ WriteUnityLog = false
|
||||
|
||||
[Preloader]
|
||||
|
||||
## Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.
|
||||
## Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.
|
||||
## This setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting.
|
||||
# Setting type: MonoModBackend
|
||||
# Default value: auto
|
||||
# Acceptable values: auto, dynamicmethod, methodbuilder, cecil
|
||||
HarmonyBackend = auto
|
||||
|
||||
## If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.
|
||||
## If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.
|
||||
## This can be used by developers to inspect and debug preloader patchers.
|
||||
# Setting type: Boolean
|
||||
# Default value: false
|
||||
DumpAssemblies = false
|
||||
|
||||
## If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.
|
||||
## This can be used to be able to load patched assemblies into debuggers like dnSpy.
|
||||
## If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.
|
||||
## This can be used to be able to load patched assemblies into debuggers like dnSpy.
|
||||
## If set to true, will override DumpAssemblies.
|
||||
# Setting type: Boolean
|
||||
# Default value: false
|
||||
LoadDumpedAssemblies = false
|
||||
|
||||
## If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.
|
||||
## If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.
|
||||
## This can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded.
|
||||
# Setting type: Boolean
|
||||
# Default value: false
|
||||
|
||||
Reference in new issue
Block a user