Mediabot v3 just received a focused antiflood hardening pass.
The goal was not to rewrite the bot.
The goal was to protect busy channels better β especially cases where several users trigger the bot at the same time β without touching the database schema.
βWhen the whole room starts casting spells at once, one shield per wizard is not enough.β πͺ
Mediabot already had antiflood protections, but they were not ideal for a channel-wide burst.
There were two existing mechanisms:
checkAntiFlood()
protects against too many outgoing bot messages per channel
uses existing DB-backed CHANNEL_FLOOD settings
checkNickFlood()
protects against one nick sending too many commands quickly
That helps when one person abuses the bot.
But it does not fully solve this situation:
nick1 -> !seen
nick2 -> !karma
nick3 -> !ai
nick4 -> !q
nick5 -> !date
Each user may stay under the per-nick limit, but the channel still causes the bot to produce too much traffic.
That is exactly the kind of pressure seen on active channels like #quebec.
checkAntiFlood() still uses the existing database-backed CHANNEL_FLOOD settings.
No schema change.
But the expensive part was improved: parameters are cached in memory instead of being queried repeatedly on every outgoing bot message.
The DB remains the source of truth for:
nbmsg_max
duration
timetowait
The runtime now keeps hot state in memory and refreshes parameters through a configurable cache TTL.
New config keys:
[antiflood]
OUTPUT_PARAMS_CACHE_TTL=60
OUTPUT_STATE_TTL=300
OUTPUT_PARAMS_STATE_TTL=600
Result: same behavior, much less synchronous DB pressure during bursts.
The per-nick limiter was improved in two ways.
First, it can now notify the user instead of failing silently.
A nick who sends too many commands can receive a NOTICE such as:
You are sending commands too fast. Please wait a few seconds.
Second, the limiter now uses a sliding timestamp window instead of a fragile fixed window.
That avoids the classic edge case:
4 commands at t=4.9s
4 commands at t=5.1s
A fixed window can let that through.
A sliding window sees the real burst.
New config keys:
[antiflood]
NICKFLOOD_WINDOW=5
NICKFLOOD_MAX_COMMANDS=5
NICKFLOOD_NOTIFY_COOLDOWN=30
NICKFLOOD_STATE_TTL=120
This is the important part for multi-user floods.
A new channel-wide input guard counts all public commands addressed to the bot on a channel, regardless of which nick sent them.
If a channel crosses the threshold, the bot temporarily silences command handling for that channel.
New config keys:
[antiflood]
CHANFLOOD_WINDOW=10
CHANFLOOD_MAX_COMMANDS=8
CHANFLOOD_SILENCE=30
CHANFLOOD_NOTIFY_COOLDOWN=60
Example logic:
more than 8 bot commands in 10 seconds on the same channel
β silence bot command handling on that channel for 30 seconds
This happens before the per-nick limiter and before expensive command handling.
That makes it much better for coordinated or accidental multi-user bursts.
One important correction was made during testing:
checkChanFlood() is intentionally public-channel only.
Private commands do not have a channel context and include login/admin workflows. They must not depend on a channel flood state.
So:
mbCommandPublic()
uses channel-wide guard
then per-nick guard
mbCommandPrivate()
does not use channel-wide guard
This avoids breaking private login, admin, and Partyline-adjacent workflows.
The antiflood work also exposes better visibility.
Metrics added or covered:
mediabot_antiflood_blocks_total
mediabot_nickflood_blocks_total
mediabot_chanflood_blocks_total
Partyline gets .floodstatus, which can show:
output antiflood state
channel input flood state
per-nick flood state
This makes it much easier to understand what is happening while the bot is under pressure.
Five static tests were added to lock this down:
334_antiflood_configurable_thresholds.t
335_antiflood_chanflood_public_only.t
336_antiflood_nickflood_sliding_notice.t
337_antiflood_output_cache_and_metrics.t
338_antiflood_partyline_floodstatus.t
They verify:
configurable thresholds
public-only channel guard
private commands not depending on channel context
sliding per-nick window
notice cooldown
output antiflood parameter cache
metrics declarations
Partyline .floodstatus coverage
The test suite is now protecting the intended design instead of merely trusting the patch.
This was deliberate.
The current pass does not add new tables and does not alter existing schema.
The existing DB-backed CHANNEL_FLOOD table remains in place for output flood settings.
The new channel and per-nick input guards are memory-backed and configured through mediabot.conf.
That keeps the change safe for existing production databases.
Mediabot now has a stronger antiflood stack:
AF1: faster outgoing channel antiflood with cached DB parameters
AF2: user notice when per-nick flood is triggered
AF3: sliding-window per-nick limiter
AF4: global channel input limiter for multi-user bursts
For busy channels, this is a major practical improvement.
It protects the bot before expensive commands run, keeps private workflows safe, adds visibility through Partyline/metrics, and avoids unnecessary database changes.
Protego Floodum!
The bot now raises a better shield when the whole channel starts casting at once.
Mischief managed β and #quebec gets a much stronger umbrella. βπͺ
You must be logged in to reply.