diff --git a/src/projections/irc/mod.rs b/src/projections/irc/mod.rs index 863203d..544694f 100644 --- a/src/projections/irc/mod.rs +++ b/src/projections/irc/mod.rs @@ -27,6 +27,11 @@ pub struct ServerConfig { #[derive(Debug)] struct RegisteredUser { nickname: Vec, + /** + * Username is mostly unused in modern IRC. + * + * [https://stackoverflow.com/questions/31666247/what-is-the-difference-between-the-nick-username-and-real-name-in-irc-and-wha] + */ username: Vec, realname: Vec, } @@ -383,39 +388,40 @@ async fn handle_incoming_message( } ClientMessage::Who { target } => match &target { Recipient::Nick(nick) => { - if nick == &user.nickname { - let mut username = Vec::with_capacity(user.username.len() + 1); - username.push(b'~'); - username.extend_from_slice(user.username.as_slice()); - ServerMessage { - tags: vec![], - sender: Some(config.server_name.as_bytes().to_vec()), - body: ServerMessageBody::N352WhoReply { - client: user.nickname.clone(), - username, - host: b"*".to_vec(), // TODO need to decide what to send as user's host - server: config.server_name.as_bytes().to_vec(), - flags: AwayStatus::Here, - hops: 0, - realname: user.realname.clone(), - }, - } - .write_async(writer) - .await?; - ServerMessage { - tags: vec![], - sender: Some(config.server_name.as_bytes().to_vec()), - body: ServerMessageBody::N315EndOfWho { - client: user.nickname.clone(), - mask: target.clone(), - msg: b"End of WHO list".to_vec(), - }, - } - .write_async(writer) - .await?; - writer.flush().await?; + // TODO handle non-existing user + let mut username = Vec::with_capacity(nick.len() + 1); + username.push(b'~'); + username.extend_from_slice(nick.as_slice()); + let mut host = b"user/".to_vec(); + host.extend_from_slice(nick.as_slice()); + ServerMessage { + tags: vec![], + sender: Some(config.server_name.as_bytes().to_vec()), + body: ServerMessageBody::N352WhoReply { + client: user.nickname.clone(), + username, + host, + server: config.server_name.as_bytes().to_vec(), + flags: AwayStatus::Here, + nickname: nick.clone(), + hops: 0, + realname: user.realname.clone(), + }, } - log::warn!("WHO for other users is not implemented") + .write_async(writer) + .await?; + ServerMessage { + tags: vec![], + sender: Some(config.server_name.as_bytes().to_vec()), + body: ServerMessageBody::N315EndOfWho { + client: user.nickname.clone(), + mask: target.clone(), + msg: b"End of WHO list".to_vec(), + }, + } + .write_async(writer) + .await?; + writer.flush().await?; } Recipient::Chan(_) => { log::warn!("WHO for chans not implemented") diff --git a/src/protos/irc/server.rs b/src/protos/irc/server.rs index bc5aeff..f4c390d 100644 --- a/src/protos/irc/server.rs +++ b/src/protos/irc/server.rs @@ -104,6 +104,7 @@ pub enum ServerMessageBody { host: ByteVec, /// Hostname of the server the user is connected to server: ByteVec, + nickname: ByteVec, /// Flags flags: AwayStatus, hops: u8, @@ -224,6 +225,7 @@ impl ServerMessageBody { host, server, flags, + nickname, hops, realname, } => { @@ -240,6 +242,8 @@ impl ServerMessageBody { AwayStatus::Here => writer.write_all(b"H").await?, AwayStatus::Gone => writer.write_all(b"G").await?, } + writer.write_all(b" ").await?; + writer.write_all(&nickname).await?; writer.write_all(b" :").await?; writer.write_all(hops.to_string().as_bytes()).await?; writer.write_all(b" ").await?;