send chat members list on connection

This commit is contained in:
Nikita Vilunov 2023-02-14 01:44:03 +01:00
parent ec819d37ea
commit cef0269828
4 changed files with 36 additions and 10 deletions

View File

@ -20,7 +20,7 @@ use tokio::{
}; };
use crate::{ use crate::{
core::room::{RoomId, RoomRegistry}, core::room::{RoomId, RoomRegistry, RoomInfo},
prelude::*, prelude::*,
util::table::{AnonTable, Key as AnonKey}, util::table::{AnonTable, Key as AnonKey},
}; };
@ -44,7 +44,7 @@ impl PlayerConnection {
.await .await
} }
pub async fn join_room(&mut self, room_id: RoomId) { pub async fn join_room(&mut self, room_id: RoomId) -> Result<RoomInfo> {
self.player_handle.join_room(room_id).await self.player_handle.join_room(room_id).await
} }
} }
@ -84,8 +84,10 @@ impl PlayerHandle {
.await; .await;
} }
pub async fn join_room(&self, room_id: RoomId) { pub async fn join_room(&self, room_id: RoomId) -> Result<RoomInfo> {
self.tx.send(PlayerCommand::JoinRoom { room_id }).await; let (promise, deferred) = oneshot();
self.tx.send(PlayerCommand::JoinRoom { room_id, promise }).await;
Ok(deferred.await?)
} }
pub async fn receive_message( pub async fn receive_message(
@ -125,6 +127,7 @@ enum PlayerCommand {
}, },
JoinRoom { JoinRoom {
room_id: RoomId, room_id: RoomId,
promise: Promise<RoomInfo>,
}, },
SendMessage { SendMessage {
room_id: RoomId, room_id: RoomId,
@ -206,9 +209,11 @@ impl Player {
let connection_id = self.sockets.insert(sender); let connection_id = self.sockets.insert(sender);
promise.send(ConnectionId(connection_id)); promise.send(ConnectionId(connection_id));
} }
PlayerCommand::JoinRoom { room_id } => { PlayerCommand::JoinRoom { room_id, promise } => {
let mut room = rooms.get_or_create_room(room_id); let mut room = rooms.get_or_create_room(room_id.clone());
room.subscribe(player_id.clone(), handle.clone()).await; room.subscribe(player_id.clone(), handle.clone()).await;
let members = room.get_members().await;
promise.send(RoomInfo { id: room_id, members, topic: b"some topic lol".to_vec() });
} }
PlayerCommand::SendMessage { PlayerCommand::SendMessage {
room_id, room_id,

View File

@ -71,7 +71,7 @@ impl RoomHandle {
} }
pub async fn send_message( pub async fn send_message(
&mut self, &self,
player_id: PlayerId, player_id: PlayerId,
connection_id: ConnectionId, connection_id: ConnectionId,
body: String, body: String,
@ -79,6 +79,11 @@ impl RoomHandle {
let lock = self.0.read().await; let lock = self.0.read().await;
lock.send_message(player_id, connection_id, body).await; lock.send_message(player_id, connection_id, body).await;
} }
pub async fn get_members(&self) -> Vec<PlayerId> {
let lock = self.0.read().await;
lock.subscriptions.keys().map(|x| x.clone()).collect::<Vec<_>>()
}
} }
struct Room { struct Room {
@ -105,3 +110,9 @@ impl Room {
} }
} }
} }
pub struct RoomInfo {
pub id: RoomId,
pub members: Vec<PlayerId>,
pub topic: ByteVec,
}

View File

@ -3,6 +3,7 @@ pub use std::future::Future;
pub use tokio::pin; pub use tokio::pin;
pub use tokio::select; pub use tokio::select;
pub use tokio::task::JoinHandle; pub use tokio::task::JoinHandle;
pub use tokio::sync::oneshot::{channel as oneshot, Receiver as Deferred, Sender as Promise};
pub mod log { pub mod log {
pub use tracing::{debug, error, info, warn}; pub use tracing::{debug, error, info, warn};

View File

@ -287,7 +287,7 @@ async fn handle_join(
) -> Result<()> { ) -> Result<()> {
match chan { match chan {
Chan::Global(ref room) => { Chan::Global(ref room) => {
user_handle.join_room(RoomId(room.clone())).await; let room_info = user_handle.join_room(RoomId(room.clone())).await?;
ServerMessage { ServerMessage {
tags: vec![], tags: vec![],
sender: Some(user.nickname.clone()), sender: Some(user.nickname.clone()),
@ -301,18 +301,27 @@ async fn handle_join(
body: ServerMessageBody::N332Topic { body: ServerMessageBody::N332Topic {
client: user.nickname.clone(), client: user.nickname.clone(),
chat: chan.clone(), chat: chan.clone(),
topic: b"chan topic lol".to_vec(), topic: room_info.topic,
}, },
} }
.write_async(writer) .write_async(writer)
.await?; .await?;
let mut members = if let Some(head) = room_info.members.first() {
head.0.clone()
} else {
user.nickname.clone()
};
for i in &room_info.members[1..] {
members.push(b' ');
members.extend(&i.0);
}
ServerMessage { ServerMessage {
tags: vec![], tags: vec![],
sender: Some(config.server_name.as_bytes().to_vec()), sender: Some(config.server_name.as_bytes().to_vec()),
body: ServerMessageBody::N353NamesReply { body: ServerMessageBody::N353NamesReply {
client: user.nickname.clone(), client: user.nickname.clone(),
chan: chan.clone(), chan: chan.clone(),
members: user.nickname.clone(), members,
}, },
} }
.write_async(writer) .write_async(writer)