chanserv: channel seen checks channel membership, not global presence
All checks were successful
CI / check (push) Successful in 3m45s

This commit is contained in:
Jean Chevronnet 2026-07-17 01:54:55 +00:00
parent 66eb644a07
commit fcca7ac12b
No known key found for this signature in database
2 changed files with 18 additions and 8 deletions

View file

@ -12,7 +12,9 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, net:
ctx.notice(me, from.uid, "Syntax: SEEN <#channel> <nick>"); ctx.notice(me, from.uid, "Syntax: SEEN <#channel> <nick>");
return; return;
}; };
if net.uid_by_nick(nick).is_some() { // Present in THIS channel right now — online elsewhere doesn't count.
let here = net.uid_by_nick(nick).is_some_and(|uid| net.channel_members(chan).iter().any(|m| m == uid));
if here {
ctx.notice(me, from.uid, format!("{}: \x02{nick}\x02 is here right now.", from.nick)); ctx.notice(me, from.uid, format!("{}: \x02{nick}\x02 is here right now.", from.nick));
return; return;
} }

View file

@ -565,17 +565,25 @@
_ => None, _ => None,
}).expect("bot joins #room"); }).expect("bot joins #room");
// bob speaks in the channel, then quits. // bob speaks in the channel but never joins it (online, not a member).
e.handle(NetEvent::UserConnect { uid: "000AAAAAB".into(), nick: "bob".into(), host: "h".into(), ip: "0.0.0.0".into() }); e.handle(NetEvent::UserConnect { uid: "000AAAAAB".into(), nick: "bob".into(), host: "h".into(), ip: "0.0.0.0".into() });
e.handle(NetEvent::Privmsg { from: "000AAAAAB".into(), to: "#room".into(), text: "bye bye friends".into() }); e.handle(NetEvent::Privmsg { from: "000AAAAAB".into(), to: "#room".into(), text: "bye bye friends".into() });
e.handle(NetEvent::Quit { uid: "000AAAAAB".into() });
// alice asks !seen bob: the bot answers in the channel with bob's last message. // Online elsewhere but not in #room -> report his last message, NOT "here".
let seen = e.handle(NetEvent::Privmsg { from: "000AAAAAA".into(), to: "#room".into(), text: "!seen bob".into() }); let away = e.handle(NetEvent::Privmsg { from: "000AAAAAA".into(), to: "#room".into(), text: "!seen bob".into() });
assert!( assert!(
seen.iter().any(|a| matches!(a, NetAction::Privmsg { from, to, text } away.iter().any(|a| matches!(a, NetAction::Privmsg { from, to, text }
if from == &botuid && to == "#room" && text.contains("bye bye friends") && text.contains("bob"))), if from == &botuid && to == "#room" && text.contains("bye bye friends") && !text.contains("here right now"))),
"bot reports bob's last message in the channel, got {seen:?}" "online-elsewhere bob: last message, not 'here', got {away:?}"
);
// Now bob is actually in the channel -> "here right now".
e.handle(NetEvent::Join { uid: "000AAAAAB".into(), channel: "#room".into(), op: false });
let here = e.handle(NetEvent::Privmsg { from: "000AAAAAA".into(), to: "#room".into(), text: "!seen bob".into() });
assert!(
here.iter().any(|a| matches!(a, NetAction::Privmsg { from, to, text }
if from == &botuid && to == "#room" && text.contains("here right now"))),
"bob in channel: 'here right now', got {here:?}"
); );
} }