handle topic command

This commit is contained in:
Nikita Vilunov 2023-02-14 19:46:42 +01:00
parent d10cddec61
commit c845f5d4ca
3 changed files with 65 additions and 5 deletions

View File

@ -136,6 +136,7 @@ pub enum Updates {
room_id: RoomId, room_id: RoomId,
body: String, body: String,
}, },
IncomingUpdate(IncomingPlayerEvent),
} }
pub enum PlayerCommand { pub enum PlayerCommand {
/** Commands from connections */ /** Commands from connections */
@ -166,6 +167,12 @@ pub enum PlayerCommand {
new_member_id: PlayerId, new_member_id: PlayerId,
connection_id: ConnectionId, 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. /// Handle to a player registry — a shared data structure containing information about players.
@ -314,6 +321,11 @@ impl Player {
.await; .await;
} }
} }
PlayerCommand::Event(event) => {
for socket in &self.sockets {
socket.send(Updates::IncomingUpdate(event.clone())).await;
}
}
} }
} }
self self

View File

@ -13,7 +13,7 @@ use crate::{
prelude::*, prelude::*,
}; };
use super::player::ConnectionId; use super::player::{ConnectionId, IncomingPlayerEvent};
/// Opaque room id /// Opaque room id
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -42,6 +42,7 @@ impl RoomRegistry {
let room = Room { let room = Room {
room_id: room_id.clone(), room_id: room_id.clone(),
subscriptions: HashMap::new(), subscriptions: HashMap::new(),
topic: b"New room".to_vec(),
}; };
let room_handle = RoomHandle(Arc::new(AsyncRwLock::new(room))); let room_handle = RoomHandle(Arc::new(AsyncRwLock::new(room)));
inner.rooms.insert(room_id, room_handle.clone()); inner.rooms.insert(room_id, room_handle.clone());
@ -103,7 +104,22 @@ impl RoomHandle {
.keys() .keys()
.map(|x| x.clone()) .map(|x| x.clone())
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
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 { struct Room {
room_id: RoomId, room_id: RoomId,
subscriptions: HashMap<PlayerId, PlayerHandle>, subscriptions: HashMap<PlayerId, PlayerHandle>,
topic: ByteVec,
} }
impl Room { impl Room {
async fn add_subscriber( async fn add_subscriber(

View File

@ -8,7 +8,7 @@ use tokio::net::{TcpListener, TcpStream};
use tokio::sync::oneshot::channel; use tokio::sync::oneshot::channel;
use crate::core::player::{ use crate::core::player::{
PlayerConnection, PlayerId, PlayerRegistry, Updates, PlayerCommand, IncomingPlayerEvent, PlayerCommand, PlayerConnection, PlayerId, PlayerRegistry, Updates,
}; };
use crate::core::room::{RoomId, RoomInfo, RoomRegistry}; use crate::core::room::{RoomId, RoomInfo, RoomRegistry};
use crate::prelude::*; use crate::prelude::*;
@ -211,7 +211,14 @@ async fn handle_registered_socket<'a>(
connection.send(PlayerCommand::GetRooms(promise)).await; connection.send(PlayerCommand::GetRooms(promise)).await;
let rooms_list = deferred.await?; let rooms_list = deferred.await?;
for room in &rooms_list { 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?; writer.flush().await?;
@ -227,7 +234,7 @@ async fn handle_registered_socket<'a>(
} else { } else {
len 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(); buffer.clear();
}, },
update = connection.receiver.recv() => { update = connection.receiver.recv() => {
@ -261,6 +268,18 @@ async fn handle_registered_socket<'a>(
writer.flush().await? 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], buffer: &[u8],
config: &ServerConfig, config: &ServerConfig,
user: &RegisteredUser, user: &RegisteredUser,
rooms: &RoomRegistry,
user_handle: &mut PlayerConnection, user_handle: &mut PlayerConnection,
writer: &mut (impl AsyncWrite + Unpin), writer: &mut (impl AsyncWrite + Unpin),
) -> Result<()> { ) -> Result<()> {
@ -305,6 +325,17 @@ async fn handle_incoming_message(
}, },
_ => log::warn!("Unsupported target type"), _ => 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) => { Err(err) => {