The IRC relay registers a broker wait channel on each pass of its
loop, and when the 100 ms ticker fired instead of a notification it
looped without removing that channel. An idle IRC listener connection
added ten channels a second to the broker, and all but the last stayed
after the connection closed. The ticker case now removes its channel,
as the HTTP long-poll does after its timer.
Broker.ListenerCount returns how many wait channels a user holds, so
the test can check that an idle connection holds at most one, and
none after it closes.
Model: opus-5-5
README.md rules that nicks are case-sensitive, but the IRC listener's
relay and user MODE on both transports compared nicks ignoring case:
an IRC listener user alice never saw a PRIVMSG, NOTICE, JOIN, PART,
NICK or QUIT from Alice, and MODE Alice from alice was taken as her
own nick. These checks now use ==.
Tests cover alice receiving each of these from Alice, MODE Alice from
alice getting 502 on both transports, and Alice registering while
alice exists. README.md drops the text that described the old
behaviour.
Model: opus-5-5
The IRC listener relayed only the first line of a PRIVMSG or NOTICE
body; it now sends one line per body line. A relayed MODE change now
carries its key, limit or mask, each value its own parameter, also in
the echo to the user who made it. CR, LF and NUL are removed from each
parameter and from each whole line sent to an IRC listener connection,
so no stored value can start a line of its own. The channel name check
moved into service.JoinChannel, so the IRC listener's JOIN refuses the
same names with 403.
Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>