refined SignEditListener to filter illegal characters more robustly by normalizing input and introducing specific character whitelists
This commit is contained in:
@@ -6,18 +6,73 @@ import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.block.SignChangeEvent;
|
import org.bukkit.event.block.SignChangeEvent;
|
||||||
|
|
||||||
|
import java.text.Normalizer;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
class SignEditListener extends ApplianceListener<AntiIllegalSignCharacters> {
|
class SignEditListener extends ApplianceListener<AntiIllegalSignCharacters> {
|
||||||
|
private static final Set<Integer> ALLOWED_CHARS = Set.of(
|
||||||
|
(int)' ', (int)'.', (int)',', (int)';', (int)':', (int)'!', (int)'?',
|
||||||
|
(int)'"', (int)'\'',
|
||||||
|
(int)'(', (int)')', (int)'[', (int)']', (int)'{', (int)'}',
|
||||||
|
(int)'-', (int)'_', (int)'+', (int)'=', (int)'/', (int)'\\',
|
||||||
|
(int)'@', (int)'#', (int)'$', (int)'%', (int)'&', (int)'*',
|
||||||
|
(int)'<', (int)'>', (int)'|',
|
||||||
|
(int)'~', (int)'`', (int)'^'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Set<Integer> ALLOWED_EXTRA = Set.of(
|
||||||
|
(int)'Ä', (int)'Ö', (int)'Ü', (int)'ä', (int)'ö', (int)'ü', (int)'ß',
|
||||||
|
(int)'€', (int)'°', (int)'µ'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onSignEdit(SignChangeEvent event) {
|
public void onSignEdit(SignChangeEvent event) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
Component line = event.line(i);
|
Component line = event.line(i);
|
||||||
if (line == null) continue;
|
if (line == null) continue;
|
||||||
String lineStr = PlainTextComponentSerializer.plainText().serialize(line);
|
String plainString = PlainTextComponentSerializer.plainText().serialize(line);
|
||||||
|
plainString = Normalizer.normalize(plainString, Normalizer.Form.NFC);
|
||||||
if (!lineStr.matches("^[ -~]*$")) {
|
String cleaned = filterAllowed(plainString);
|
||||||
String cleaned = lineStr.replaceAll("[^ -~]", "");
|
|
||||||
event.line(i, Component.text(cleaned));
|
event.line(i, Component.text(cleaned));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String filterAllowed(String s) {
|
||||||
|
StringBuilder out = new StringBuilder(s.length());
|
||||||
|
|
||||||
|
for (int off = 0; off < s.length(); ) {
|
||||||
|
int cp = s.codePointAt(off);
|
||||||
|
off += Character.charCount(cp);
|
||||||
|
|
||||||
|
if (isForbidden(cp)) continue;
|
||||||
|
|
||||||
|
if (Character.isLetterOrDigit(cp)) {
|
||||||
|
out.appendCodePoint(cp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ALLOWED_CHARS.contains(cp) || ALLOWED_EXTRA.contains(cp)) {
|
||||||
|
out.appendCodePoint(cp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isForbidden(int cp) {
|
||||||
|
// Surrogates / invalid
|
||||||
|
if (cp >= 0xD800 && cp <= 0xDFFF) return true;
|
||||||
|
|
||||||
|
// Private Use Area (Mod/Pack-Icons/Placeholder)
|
||||||
|
if (cp >= 0xE000 && cp <= 0xF8FF) return true;
|
||||||
|
|
||||||
|
// Zero-width and control characters
|
||||||
|
if (cp == 0x200B || cp == 0x200C || cp == 0x200D || cp == 0xFEFF) return true;
|
||||||
|
|
||||||
|
// BiDi-Steuerzeichen
|
||||||
|
if (cp >= 0x202A && cp <= 0x202E) return true;
|
||||||
|
if (cp >= 0x2066 && cp <= 0x2069) return true;
|
||||||
|
|
||||||
|
return cp == '§';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user