diff --git a/src/bin/poc-daemon/modules/irc.rs b/src/bin/poc-daemon/modules/irc.rs index ee0d17b..a93030c 100644 --- a/src/bin/poc-daemon/modules/irc.rs +++ b/src/bin/poc-daemon/modules/irc.rs @@ -263,7 +263,7 @@ async fn connect_and_run( async fn register_and_read( state: &SharedIrc, config: &IrcConfig, - reader: BufReader, + mut reader: BufReader, notify_tx: &mpsc::UnboundedSender, ) -> io::Result<()> { // Register @@ -273,9 +273,15 @@ async fn register_and_read( s.send_raw(&format!("USER {} 0 * :{}", config.user, config.realname)).await?; } - let mut lines = reader.lines(); + let mut buf = Vec::new(); - while let Some(line) = lines.next_line().await? { + loop { + buf.clear(); + let n = reader.read_until(b'\n', &mut buf).await?; + if n == 0 { break; } + // IRC is not guaranteed UTF-8 — lossy conversion handles Latin-1 etc. + let line = String::from_utf8_lossy(&buf).trim_end().to_string(); + if line.is_empty() { continue; } let msg = match IrcMessage::parse(&line) { Some(m) => m, None => continue, @@ -306,6 +312,19 @@ async fn register_and_read( let text = msg.params.get(1).map(|s| s.as_str()).unwrap_or(""); let nick = msg.nick().unwrap_or("unknown"); + // Handle CTCP requests (wrapped in \x01) + if text.starts_with('\x01') && text.ends_with('\x01') { + let ctcp = &text[1..text.len()-1]; + if ctcp.starts_with("VERSION") { + let reply = format!( + "NOTICE {nick} :\x01VERSION poc-daemon 0.4.0\x01" + ); + state.borrow_mut().send_raw(&reply).await.ok(); + } + // Don't generate notifications for CTCP + continue; + } + // Log the message let log_line = if target.starts_with('#') { format!("[{}] <{}> {}", target, nick, text) @@ -453,11 +472,13 @@ pub async fn handle_command( } let target = &args[0]; let msg = args[1..].join(" "); + let nick = state.borrow().config.nick.clone(); state .borrow_mut() .send_privmsg(target, &msg) .await .map_err(|e| e.to_string())?; + append_log(target, &nick, &msg); Ok(format!("sent to {target}")) } "status" => {