diff --git a/src/core/player.rs b/src/core/player.rs index e31e977..6e87f92 100644 --- a/src/core/player.rs +++ b/src/core/player.rs @@ -20,7 +20,7 @@ use tokio::{ }; use crate::{ - core::room::{RoomId, RoomRegistry}, + core::room::{RoomId, RoomRegistry, RoomInfo}, prelude::*, util::table::{AnonTable, Key as AnonKey}, }; @@ -44,7 +44,7 @@ impl PlayerConnection { .await } - pub async fn join_room(&mut self, room_id: RoomId) { + pub async fn join_room(&mut self, room_id: RoomId) -> Result { self.player_handle.join_room(room_id).await } } @@ -84,8 +84,10 @@ impl PlayerHandle { .await; } - pub async fn join_room(&self, room_id: RoomId) { - self.tx.send(PlayerCommand::JoinRoom { room_id }).await; + pub async fn join_room(&self, room_id: RoomId) -> Result { + let (promise, deferred) = oneshot(); + self.tx.send(PlayerCommand::JoinRoom { room_id, promise }).await; + Ok(deferred.await?) } pub async fn receive_message( @@ -125,6 +127,7 @@ enum PlayerCommand { }, JoinRoom { room_id: RoomId, + promise: Promise, }, SendMessage { room_id: RoomId, @@ -206,9 +209,11 @@ impl Player { let connection_id = self.sockets.insert(sender); promise.send(ConnectionId(connection_id)); } - PlayerCommand::JoinRoom { room_id } => { - let mut room = rooms.get_or_create_room(room_id); + PlayerCommand::JoinRoom { room_id, promise } => { + let mut room = rooms.get_or_create_room(room_id.clone()); 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 { room_id, diff --git a/src/core/room.rs b/src/core/room.rs index c725740..1a29392 100644 --- a/src/core/room.rs +++ b/src/core/room.rs @@ -71,7 +71,7 @@ impl RoomHandle { } pub async fn send_message( - &mut self, + &self, player_id: PlayerId, connection_id: ConnectionId, body: String, @@ -79,6 +79,11 @@ impl RoomHandle { let lock = self.0.read().await; lock.send_message(player_id, connection_id, body).await; } + + pub async fn get_members(&self) -> Vec { + let lock = self.0.read().await; + lock.subscriptions.keys().map(|x| x.clone()).collect::>() + } } struct Room { @@ -105,3 +110,9 @@ impl Room { } } } + +pub struct RoomInfo { + pub id: RoomId, + pub members: Vec, + pub topic: ByteVec, +} diff --git a/src/prelude.rs b/src/prelude.rs index c19614d..d9dd2c2 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -3,6 +3,7 @@ pub use std::future::Future; pub use tokio::pin; pub use tokio::select; pub use tokio::task::JoinHandle; +pub use tokio::sync::oneshot::{channel as oneshot, Receiver as Deferred, Sender as Promise}; pub mod log { pub use tracing::{debug, error, info, warn}; diff --git a/src/projections/irc/mod.rs b/src/projections/irc/mod.rs index de4e141..f68aae7 100644 --- a/src/projections/irc/mod.rs +++ b/src/projections/irc/mod.rs @@ -287,7 +287,7 @@ async fn handle_join( ) -> Result<()> { match chan { Chan::Global(ref room) => { - user_handle.join_room(RoomId(room.clone())).await; + let room_info = user_handle.join_room(RoomId(room.clone())).await?; ServerMessage { tags: vec![], sender: Some(user.nickname.clone()), @@ -301,18 +301,27 @@ async fn handle_join( body: ServerMessageBody::N332Topic { client: user.nickname.clone(), chat: chan.clone(), - topic: b"chan topic lol".to_vec(), + topic: room_info.topic, }, } .write_async(writer) .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 { tags: vec![], sender: Some(config.server_name.as_bytes().to_vec()), body: ServerMessageBody::N353NamesReply { client: user.nickname.clone(), chan: chan.clone(), - members: user.nickname.clone(), + members, }, } .write_async(writer)