diff --git a/bin/ircd/src/main.rs b/bin/ircd/src/main.rs index 5c7f8a164..e26313558 100644 --- a/bin/ircd/src/main.rs +++ b/bin/ircd/src/main.rs @@ -99,7 +99,7 @@ impl Ircd { // Try to potentially decrypt the incoming message. if conn.configured_chans.contains_key(&msg.channel) { - let chan_info = conn.configured_chans.get(&msg.channel).unwrap(); + let chan_info = conn.configured_chans.get_mut(&msg.channel).unwrap(); if !chan_info.joined { continue } @@ -116,8 +116,13 @@ impl Ircd { msg.message = decrypted_msg.unwrap(); info!("Decrypted received message: {:?}", msg); + } + // add the nickname to the channel's names + if !chan_info.names.contains(&msg.nickname) { + chan_info.names.push(msg.nickname.clone()); + } } conn.reply(&msg.to_irc_msg()).await?; @@ -144,7 +149,7 @@ impl Ircd { }; } }) - .detach(); + .detach(); Ok(()) } diff --git a/bin/ircd/src/server.rs b/bin/ircd/src/server.rs index 1a6374725..a2471f4da 100644 --- a/bin/ircd/src/server.rs +++ b/bin/ircd/src/server.rs @@ -15,6 +15,7 @@ use crate::{ const RPL_NOTOPIC: u32 = 331; const RPL_TOPIC: u32 = 332; +const RPL_NAMEREPLY: u32 = 353; pub struct IrcServerConnection { // server stream @@ -70,6 +71,33 @@ impl IrcServerConnection { // Ignore it for now. self.is_user_init = true; } + "NAMES" => { + let channels = tokens.next().ok_or(Error::MalformedPacket)?; + for chan in channels.split(',') { + if !chan.starts_with('#') { + warn!("{} is not a valid name for channel", chan); + continue + } + + if self.configured_chans.contains_key(chan) { + let chan_info = self.configured_chans.get(chan).unwrap(); + + if chan_info.names.is_empty() { + continue + } + + let names_reply = format!( + ":{}!anon@dark.fi {} = {} : {}\r\n", + self.nickname, + RPL_NAMEREPLY, + chan, + chan_info.names.join(" ") + ); + + self.reply(&names_reply).await?; + } + } + } "NICK" => { let nickname = tokens.next().ok_or(Error::MalformedPacket)?; self.is_nick_init = true; diff --git a/bin/ircd/src/settings.rs b/bin/ircd/src/settings.rs index 8f09be62e..6f1689632 100644 --- a/bin/ircd/src/settings.rs +++ b/bin/ircd/src/settings.rs @@ -67,11 +67,13 @@ pub struct ChannelInfo { pub salt_box: Option, /// Flag indicates whether the user has joined the channel or not pub joined: bool, + /// All nicknames which are visible on the channel + pub names: Vec, } impl ChannelInfo { pub fn new() -> Result { - Ok(Self { topic: None, salt_box: None, joined: true }) + Ok(Self { topic: None, salt_box: None, joined: true, names: vec![] }) } }