fix WHO replies

This commit is contained in:
Nikita Vilunov 2023-02-16 19:33:36 +01:00
parent 81ee1c1044
commit 69bccef3bf
2 changed files with 42 additions and 32 deletions

View File

@ -27,6 +27,11 @@ pub struct ServerConfig {
#[derive(Debug)] #[derive(Debug)]
struct RegisteredUser { struct RegisteredUser {
nickname: Vec<u8>, nickname: Vec<u8>,
/**
* 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<u8>, username: Vec<u8>,
realname: Vec<u8>, realname: Vec<u8>,
} }
@ -383,39 +388,40 @@ async fn handle_incoming_message(
} }
ClientMessage::Who { target } => match &target { ClientMessage::Who { target } => match &target {
Recipient::Nick(nick) => { Recipient::Nick(nick) => {
if nick == &user.nickname { // TODO handle non-existing user
let mut username = Vec::with_capacity(user.username.len() + 1); let mut username = Vec::with_capacity(nick.len() + 1);
username.push(b'~'); username.push(b'~');
username.extend_from_slice(user.username.as_slice()); username.extend_from_slice(nick.as_slice());
ServerMessage { let mut host = b"user/".to_vec();
tags: vec![], host.extend_from_slice(nick.as_slice());
sender: Some(config.server_name.as_bytes().to_vec()), ServerMessage {
body: ServerMessageBody::N352WhoReply { tags: vec![],
client: user.nickname.clone(), sender: Some(config.server_name.as_bytes().to_vec()),
username, body: ServerMessageBody::N352WhoReply {
host: b"*".to_vec(), // TODO need to decide what to send as user's host client: user.nickname.clone(),
server: config.server_name.as_bytes().to_vec(), username,
flags: AwayStatus::Here, host,
hops: 0, server: config.server_name.as_bytes().to_vec(),
realname: user.realname.clone(), flags: AwayStatus::Here,
}, nickname: nick.clone(),
} hops: 0,
.write_async(writer) realname: user.realname.clone(),
.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?;
} }
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(_) => { Recipient::Chan(_) => {
log::warn!("WHO for chans not implemented") log::warn!("WHO for chans not implemented")

View File

@ -104,6 +104,7 @@ pub enum ServerMessageBody {
host: ByteVec, host: ByteVec,
/// Hostname of the server the user is connected to /// Hostname of the server the user is connected to
server: ByteVec, server: ByteVec,
nickname: ByteVec,
/// Flags /// Flags
flags: AwayStatus, flags: AwayStatus,
hops: u8, hops: u8,
@ -224,6 +225,7 @@ impl ServerMessageBody {
host, host,
server, server,
flags, flags,
nickname,
hops, hops,
realname, realname,
} => { } => {
@ -240,6 +242,8 @@ impl ServerMessageBody {
AwayStatus::Here => writer.write_all(b"H").await?, AwayStatus::Here => writer.write_all(b"H").await?,
AwayStatus::Gone => writer.write_all(b"G").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(b" :").await?;
writer.write_all(hops.to_string().as_bytes()).await?; writer.write_all(hops.to_string().as_bytes()).await?;
writer.write_all(b" ").await?; writer.write_all(b" ").await?;