forked from lavina/lavina
1
0
Fork 0

support who for global channels

This commit is contained in:
Nikita Vilunov 2023-02-16 19:47:51 +01:00
parent 69bccef3bf
commit 63f31aa42f
1 changed files with 56 additions and 14 deletions

View File

@ -29,7 +29,7 @@ struct RegisteredUser {
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>,
@ -226,7 +226,7 @@ async fn handle_registered_socket<'a>(
} else {
len
};
handle_incoming_message(&buffer[0..len], &config, &user, &mut connection, writer).await?;
handle_incoming_message(&buffer[0..len], &config, &user, &rooms, &mut connection, writer).await?;
buffer.clear();
},
update = connection.receiver.recv() => {
@ -328,6 +328,7 @@ async fn handle_incoming_message(
buffer: &[u8],
config: &ServerConfig,
user: &RegisteredUser,
rooms: &RoomRegistry,
user_handle: &mut PlayerConnection,
writer: &mut (impl AsyncWrite + Unpin),
) -> Result<()> {
@ -397,16 +398,7 @@ async fn handle_incoming_message(
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(),
},
body: user_to_who_msg(config, user, nick),
}
.write_async(writer)
.await?;
@ -423,8 +415,35 @@ async fn handle_incoming_message(
.await?;
writer.flush().await?;
}
Recipient::Chan(_) => {
log::warn!("WHO for chans not implemented")
Recipient::Chan(Chan::Global(chan)) => {
let room = rooms.get_room(&RoomId::from_bytes(chan.clone())?);
if let Some(room) = room {
let room_info = room.get_room_info().await;
for member in room_info.members {
ServerMessage {
tags: vec![],
sender: Some(config.server_name.as_bytes().to_vec()),
body: user_to_who_msg(config, user, member.as_bytes()),
}
.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(Chan::Local(_)) => {
log::warn!("Local chans not supported");
}
},
cmd => {
@ -438,6 +457,29 @@ async fn handle_incoming_message(
Ok(())
}
fn user_to_who_msg(config: &ServerConfig, requestor: &RegisteredUser, target_user_nickname: &ByteVec) -> ServerMessageBody {
// Username is equal to nickname
let mut username = Vec::with_capacity(target_user_nickname.len() + 1);
username.push(b'~');
username.extend_from_slice(target_user_nickname.as_slice());
// User's host is not public, replace it with `user/<nickname>` pattern
let mut host = b"user/".to_vec();
host.extend_from_slice(target_user_nickname.as_slice());
ServerMessageBody::N352WhoReply {
client: requestor.nickname.clone(),
username,
host,
server: config.server_name.as_bytes().to_vec(),
flags: AwayStatus::Here,
nickname: target_user_nickname.clone(),
hops: 0,
// TODO Realname is not available yet, should be matched to a future core's player field
realname: target_user_nickname.clone(),
}
}
async fn handle_join(
config: &ServerConfig,
user: &RegisteredUser,