From fcca7ac12ba608679e6e44db8895cbdcd4340c22 Mon Sep 17 00:00:00 2001 From: Jean Date: Fri, 17 Jul 2026 01:54:55 +0000 Subject: [PATCH] chanserv: channel seen checks channel membership, not global presence --- modules/chanserv/src/seen.rs | 4 +++- src/engine/tests.rs | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/modules/chanserv/src/seen.rs b/modules/chanserv/src/seen.rs index f17b0c0..0ad004c 100644 --- a/modules/chanserv/src/seen.rs +++ b/modules/chanserv/src/seen.rs @@ -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> "); 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)); return; } diff --git a/src/engine/tests.rs b/src/engine/tests.rs index 7d9467c..e7d55b6 100644 --- a/src/engine/tests.rs +++ b/src/engine/tests.rs @@ -565,17 +565,25 @@ _ => None, }).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::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. - let seen = e.handle(NetEvent::Privmsg { from: "000AAAAAA".into(), to: "#room".into(), text: "!seen bob".into() }); + // Online elsewhere but not in #room -> report his last message, NOT "here". + let away = e.handle(NetEvent::Privmsg { from: "000AAAAAA".into(), to: "#room".into(), text: "!seen bob".into() }); assert!( - seen.iter().any(|a| matches!(a, NetAction::Privmsg { from, to, text } - if from == &botuid && to == "#room" && text.contains("bye bye friends") && text.contains("bob"))), - "bot reports bob's last message in the channel, got {seen:?}" + away.iter().any(|a| matches!(a, NetAction::Privmsg { from, to, text } + if from == &botuid && to == "#room" && text.contains("bye bye friends") && !text.contains("here right now"))), + "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:?}" ); }