From c845f5d4cae2521842f0eec4d90c656660604026 Mon Sep 17 00:00:00 2001 From: Nikita Vilunov Date: Tue, 14 Feb 2023 19:46:42 +0100 Subject: [PATCH] handle topic command --- src/core/player.rs | 12 ++++++++++++ src/core/room.rs | 21 +++++++++++++++++++-- src/projections/irc/mod.rs | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/core/player.rs b/src/core/player.rs index a150d94..0df6924 100644 --- a/src/core/player.rs +++ b/src/core/player.rs @@ -136,6 +136,7 @@ pub enum Updates { room_id: RoomId, body: String, }, + IncomingUpdate(IncomingPlayerEvent), } pub enum PlayerCommand { /** Commands from connections */ @@ -166,6 +167,12 @@ pub enum PlayerCommand { new_member_id: PlayerId, connection_id: ConnectionId, }, + Event(IncomingPlayerEvent), +} + +#[derive(Clone)] +pub enum IncomingPlayerEvent { + IncomingRoomTopicChanged { room_id: RoomId, new_topic: ByteVec }, } /// Handle to a player registry — a shared data structure containing information about players. @@ -314,6 +321,11 @@ impl Player { .await; } } + PlayerCommand::Event(event) => { + for socket in &self.sockets { + socket.send(Updates::IncomingUpdate(event.clone())).await; + } + } } } self diff --git a/src/core/room.rs b/src/core/room.rs index cb7706b..359a7a3 100644 --- a/src/core/room.rs +++ b/src/core/room.rs @@ -13,7 +13,7 @@ use crate::{ prelude::*, }; -use super::player::ConnectionId; +use super::player::{ConnectionId, IncomingPlayerEvent}; /// Opaque room id #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -42,6 +42,7 @@ impl RoomRegistry { let room = Room { room_id: room_id.clone(), subscriptions: HashMap::new(), + topic: b"New room".to_vec(), }; let room_handle = RoomHandle(Arc::new(AsyncRwLock::new(room))); inner.rooms.insert(room_id, room_handle.clone()); @@ -103,7 +104,22 @@ impl RoomHandle { .keys() .map(|x| x.clone()) .collect::>(), - topic: b"some topic lol".to_vec(), + topic: lock.topic.clone(), + } + } + + pub async fn set_topic(&mut self, new_topic: ByteVec) { + let mut lock = self.0.write().await; + lock.topic = new_topic.clone(); + for (player_id, player_handle) in &lock.subscriptions { + let msg = player_handle + .send(PlayerCommand::Event( + IncomingPlayerEvent::IncomingRoomTopicChanged { + room_id: lock.room_id.clone(), + new_topic: new_topic.clone(), + }, + )) + .await; } } } @@ -111,6 +127,7 @@ impl RoomHandle { struct Room { room_id: RoomId, subscriptions: HashMap, + topic: ByteVec, } impl Room { async fn add_subscriber( diff --git a/src/projections/irc/mod.rs b/src/projections/irc/mod.rs index 74ba678..ccb38ca 100644 --- a/src/projections/irc/mod.rs +++ b/src/projections/irc/mod.rs @@ -8,7 +8,7 @@ use tokio::net::{TcpListener, TcpStream}; use tokio::sync::oneshot::channel; use crate::core::player::{ - PlayerConnection, PlayerId, PlayerRegistry, Updates, PlayerCommand, + IncomingPlayerEvent, PlayerCommand, PlayerConnection, PlayerId, PlayerRegistry, Updates, }; use crate::core::room::{RoomId, RoomInfo, RoomRegistry}; use crate::prelude::*; @@ -211,7 +211,14 @@ async fn handle_registered_socket<'a>( connection.send(PlayerCommand::GetRooms(promise)).await; let rooms_list = deferred.await?; for room in &rooms_list { - produce_on_join_cmd_messages(&config, &user, &Chan::Global(room.id.0.clone()), room, writer).await?; + produce_on_join_cmd_messages( + &config, + &user, + &Chan::Global(room.id.0.clone()), + room, + writer, + ) + .await?; } writer.flush().await?; @@ -227,7 +234,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() => { @@ -261,6 +268,18 @@ async fn handle_registered_socket<'a>( writer.flush().await? } }, + Updates::IncomingUpdate(IncomingPlayerEvent::IncomingRoomTopicChanged { room_id, new_topic }) => { + ServerMessage { + tags: vec![], + sender: Some(config.server_name.as_bytes().to_vec()), + body: ServerMessageBody::N332Topic { + client: user.nickname.clone(), + chat: Chan::Global(room_id.0.clone()), + topic: new_topic, + }, + }.write_async(writer).await?; + writer.flush().await? + }, } } } @@ -272,6 +291,7 @@ async fn handle_incoming_message( buffer: &[u8], config: &ServerConfig, user: &RegisteredUser, + rooms: &RoomRegistry, user_handle: &mut PlayerConnection, writer: &mut (impl AsyncWrite + Unpin), ) -> Result<()> { @@ -305,6 +325,17 @@ async fn handle_incoming_message( }, _ => log::warn!("Unsupported target type"), }, + ClientMessage::Topic { chan, topic } => { + match chan { + Chan::Global(ref room) => { + let room = rooms.get_room(&RoomId(room.clone())); + if let Some(mut room) = room { + room.set_topic(topic).await; + } + } + Chan::Local(_) => {} + }; + } _ => {} }, Err(err) => {