|
@@ -15,7 +15,7 @@
|
|
|
|
|
|
#pragma newdecls required
|
|
|
|
|
|
-#define PLUGIN_VERSION "1.0.1"
|
|
|
+#define PLUGIN_VERSION "1.0.2"
|
|
|
public Plugin myinfo = {
|
|
|
name = "[CSRD] Name Filter",
|
|
|
author = "nosoop",
|
|
@@ -27,10 +27,23 @@ public Plugin myinfo = {
|
|
|
|
|
|
#define UNPRINTABLE_NAME_USER_FORMAT "unprintable (%d)"
|
|
|
|
|
|
-int g_FilteredWhitespace[] = {
|
|
|
+int g_FilteredMultiByteWhitespace[] = {
|
|
|
0xe2a080, // braille pattern blank U+2800
|
|
|
- 0x0a, // linefeed
|
|
|
- 0x0d, // carriage return
|
|
|
+ 0xe2819f, // medium mathematical space U+205F
|
|
|
+
|
|
|
+ /* invisible math operators, &c. (char & 0xe281a0) */
|
|
|
+ 0xe281a0, // word joiner U+2060
|
|
|
+ 0xe281a1, // function application U+2061
|
|
|
+ 0xe281a2, // invisible times U+2062
|
|
|
+ 0xe281a3, // invisible separator U+2063
|
|
|
+ 0xe281a4, // invisible plus U+2064
|
|
|
+
|
|
|
+ 0xe281aa, // inhibit symmetric swapping U+206A
|
|
|
+ 0xe281ab, // activate symmetric swapping U+206B
|
|
|
+ 0xe281ac, // inhibit arabic form shaping U+206C
|
|
|
+ 0xe281ad, // activate arabic form shaping U+206D
|
|
|
+ 0xe281ae, // national digit shapes U+206E
|
|
|
+ 0xe281af, // nominal digit shapes U+206F
|
|
|
0
|
|
|
};
|
|
|
|
|
@@ -68,10 +81,19 @@ void OnNameUpdated(int client) {
|
|
|
bool bCharFiltered;
|
|
|
|
|
|
// Filter out non-printing characters that can't be handled elsewhere.
|
|
|
- int c;
|
|
|
- do {
|
|
|
- bCharFiltered |= (fullChar == g_FilteredWhitespace[c]);
|
|
|
- } while (g_FilteredWhitespace[++c] != 0 && !bCharFiltered);
|
|
|
+ switch (nCharBytes) {
|
|
|
+ case 3: {
|
|
|
+ // filter unicode invisible characters
|
|
|
+ bCharFiltered |= IsUnicodeCharInvisible(fullChar);
|
|
|
+ }
|
|
|
+ case 1: {
|
|
|
+ // filter out newlines
|
|
|
+ bCharFiltered |= (fullChar == 0x0d || fullChar == 0x0a);
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ // unhandled
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (!bCharFiltered) {
|
|
|
// it's a character we're not filtering
|
|
@@ -105,6 +127,17 @@ void OnNameUpdated(int client) {
|
|
|
// TODO else not name changed, but check if we can do other non-filter stuff? (trim)
|
|
|
}
|
|
|
|
|
|
+bool IsUnicodeCharInvisible(int uchar) {
|
|
|
+ int c;
|
|
|
+ do {
|
|
|
+ if (uchar == g_FilteredMultiByteWhitespace[c]) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } while (g_FilteredMultiByteWhitespace[++c] != 0);
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Attempts to lock the specified client's name with the existing `namelockid` command.
|
|
|
*/
|