Commit graph

8 commits

Author SHA1 Message Date
ad2a623120
Group the module crates under modules/
The service pseudo-clients and the ircd protocol link sat flat at the
repo root, mixed in with the daemon core and the SDK. Move them all
under modules/ so the tree separates concerns cleanly: the daemon in
src/, the SDK every module links against in api/, and the loadable
modules — the pseudo-clients plus the protocol link — in modules/.

Workspace members, the daemon's per-crate dependency paths, and each
module's api path are updated to match; the docs follow. No code change.
2026-07-14 14:19:43 +00:00
5d1bfb3144
BotServ: DONTKICKVOICES, plus neutral code comments
KICK <#channel> DONTKICKVOICES <on|off> exempts voiced users from the
kickers. The network view now tracks +v the same way it tracks +o: a new
ChannelVoice event is parsed from FMODE +v/-v and from +v join prefixes,
and set_voice/is_voiced mirror set_op/is_op (voice is cleared on part and
quit). scan_ops generalised to scan_status for any status letter.

Also scrubbed third-party project name-drops from code comments.
2026-07-13 18:19:37 +00:00
47b1fd351e
BotServ: KICK <#channel> WARN — one warning before the first kick
With WARN on, a user's first kicker offence gets a private warning from
the bot instead of a kick; the next one is kicked (and then TTB can ban).
The warned flag rides the existing per-user chatter state.
2026-07-13 17:57:40 +00:00
0edc4d4e87
BotServ: KICK <#channel> TEST <message> dry-run
Reports which content kicker (caps/formatting/badwords) a line would trip,
without kicking anyone — so an op can tune caps% or a badword regex safely.
Reuses the typed KickerSettings::violation() and the shared badword-set
builder (moved to db so the test and the live path share it).
2026-07-13 17:53:13 +00:00
ec3205bf75
BotServ kickers: times-to-ban (TTB) + BANEXPIRE
KICK <#channel> TTB <n> makes the bot ban a user after they've been
kicked n times (by any kicker) instead of only kicking; SET <#channel>
BANEXPIRE <duration|off> controls how long that ban lasts. One clear
per-channel knob rather than Anope's per-kicker ttb array.

The kick count rides in the existing ephemeral per-user chatter state, so
it's dropped when the user parts or quits. On the ban the bot sets +b on
an ideal host mask and, if BANEXPIRE is set, queues an unban that is swept
off the next event — no timer thread. Ban time is injectable for tests.
2026-07-13 17:12:12 +00:00
ca95184359
BotServ BADWORDS: user-configurable regex kicker
BADWORDS <#channel> ADD|DEL|LIST|CLEAR manages a channel's badword
patterns, each a regular expression, so a channel matches whatever it
wants — an improvement over Anope's fixed ANY/SINGLE/START/END. Enable
with KICK <#channel> BADWORDS ON.

Uses the regex crate: it's finite-automata based with linear-time
matching, so untrusted user patterns can't cause catastrophic
backtracking (ReDoS). A channel's patterns compile into one RegexSet
(single-pass match against all of them), cached in the engine and rebuilt
only when the list's revision changes — so the hot path is one is_match
call, no per-message compilation or allocation. Patterns are validated
(and size-limited) at add time; matching is case-insensitive by default.
2026-07-13 16:16:44 +00:00
43def8ee23
BotServ kickers: FLOOD and REPEAT
KICK <#channel> FLOOD ON [lines [secs]] kicks a user who sends too many
lines too fast (default 6 in 10s); KICK <#channel> REPEAT ON [times]
kicks one who repeats the same line (default 3, case-insensitive).

These are stateful, so the engine keeps per-channel/per-user counters in
an ephemeral map that is never event-logged. Hot-path conscious: a channel
with no kickers costs one lookup and returns; a returning speaker allocates
nothing (get_mut, not entry); repeat comparison is an allocation-free
case-folding 64-bit hash. Counters are dropped when a user parts or quits,
so the map stays bounded. Flood time is injectable for deterministic tests.
2026-07-13 15:18:39 +00:00
ed7da9c713
BotServ kickers: caps + formatting, with DONTKICKOPS
The assigned bot now enforces kickers on channel lines: KICK <#channel>
CAPS ON [min [percent]], and BOLDS/COLORS/UNDERLINES/REVERSES/ITALICS
for control-code formatting. DONTKICKOPS exempts channel operators. A
tripping line is kicked by the bot itself.

Kicker config is a typed KickerSettings struct on the channel (event-
sourced like ChanSettings) with a violation() check; the engine runs it
on every channel PRIVMSG. Factored the founder-or-admin gate into a
shared require_channel_admin helper (assign/set/kick).
2026-07-13 14:54:14 +00:00