Chat filter
Six layered defences against spam, abuse, advertising and bypass attempts. Each layer can be tuned individually; violations contribute points that escalate from warning to mute to ban automatically.

What the filter blocks (out of the box)
- Similarity — repeated near-identical messages, tunable threshold.
- Anti-flood — overlong messages and repeated character runs (
aaaaaaaa). - Anti-caps — too many uppercase letters relative to lowercase.
- Cooldown — minimum seconds between messages per player.
- Bad-word lists — categorised: swearing, racism, threats. Each category has its own point value.
- Default rules — IPs, URLs, domains, phone numbers, spaced domains, coordinate sharing, unicode abuse.
Quick tune (chat-filter.yml)
similarity-check:
enabled: true
threshold: 0.75 # 0.0 = identical, 1.0 = totally different
anti-flood:
enabled: true
max-length-message: 150
max-repeated-characters: 4
broadcastStaff: true
anti-caps:
enabled: true
max-caps: 5 # max consecutive uppercase chars
cooldown-messages:
enabled: true
seconds: 3
chat-rules:
enabled: true
replace-with: '*'
cancel-message: true
alert-staff: true
use-aggressive-regexes: false # turn on for leet-speak normalization
default-rules:
block-ips: true
block-url: true
block-domains: true
block-phone-numbers: true
block-all-unicodes: false
detect-spaced-domains: true
coordinate-protection: truePoint-based escalation
Every violation type has a point value. Points accumulate per-player. When a configured threshold is reached, the matching action runs as console — typically a warn, mute, or ban via your existing punishment plugin.
actions-and-points:
enabled: true
persist-across-sessions: true # don't reset on disconnect
points:
ip: 5
url: 5
domain: 4
phone: 4
unicode: 1
bad-word: 3 # may be overridden by category in filter-rules.yml
regex: 5
spam: 2 # cooldown / similarity / flood
notify-player:
enabled: true
threshold: 10
message: '&#EEA7B9⚠ Warning: You have accumulated &#F2E8DC%points% &#EEA7B9infraction points.'
reset-points:
enabled: true
after-last-infraction: 30 # minutes of no infractions before reset
actions-when-points-reached:
warning_action:
points-required: 15
once-only: true
commands-to-execute:
- 'warn %player_name% Repeated chat violations'
mute_action:
points-required: 40
once-only: true
notify-player: '&#EEA7B9⚠ You have been muted for 30 minutes.'
commands-to-execute:
- 'tempmute %player_name% 30m Repeated filter violations'
ban_action:
points-required: 100
once-only: true
commands-to-execute:
- 'tempban %player_name% 1d Excessive filter violations'Bad-word categories
filter/filter-rules.yml ships an EN/ES baseline. Each category groups related words and assigns a point value. Heavier categories (racism, threats) escalate faster.
rules:
swearing:
points: 3
words:
- fuck
- shit
- asshole
# ...
racism:
points: 10 # heavier — kicks toward mute fast
words:
- <truncated>
threats:
points: 8
words:
- 'kill yourself'
- kys
- '%player% is a target'Word boundary matching (default)
Patterns are wrapped in \bso short words don't match inside longer ones — ho won't fire on hola, ass won't fire on class.
Aggressive mode (opt-in)
Set use-aggressive-regexes: true to normalize leet-speak before matching: fck, f.u.c.k, ph_uck all match fuck.
Watching it work
Discord webhook (optional)
Pipe filter alerts to a private Discord channel for moderation review.
discord-webhook:
enabled: true
url: 'https://discord.com/api/webhooks/…'Bypass permissions
starchat.filter.bypass— bypasses everything (default op).starchat.filter.bypass.cooldown,...caps,...words,...urls,...spam— granular bypasses for staff or trusted ranks.