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,
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

View File

@ -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::<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 {
room_id: RoomId,
subscriptions: HashMap<PlayerId, PlayerHandle>,
topic: ByteVec,
}
impl Room {
async fn add_subscriber(

View File

@ -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) => {