diff options
| author | metamuffin <metamuffin@disroot.org> | 2023-09-08 00:24:58 +0200 | 
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2023-09-08 00:24:58 +0200 | 
| commit | 3f62287bc7052d81778a6c8b3a0b5682c18c4f62 (patch) | |
| tree | e307bf9efeae3848242509ec3b97040aee8932a4 /server | |
| parent | f5fa4f7d58344c2dc722d1f37c1d7a008f6ee9b3 (diff) | |
| download | keks-meet-3f62287bc7052d81778a6c8b3a0b5682c18c4f62.tar keks-meet-3f62287bc7052d81778a6c8b3a0b5682c18c4f62.tar.bz2 keks-meet-3f62287bc7052d81778a6c8b3a0b5682c18c4f62.tar.zst | |
room watches
Diffstat (limited to 'server')
| -rw-r--r-- | server/src/config.rs | 1 | ||||
| -rw-r--r-- | server/src/logic.rs | 118 | ||||
| -rw-r--r-- | server/src/main.rs | 16 | 
3 files changed, 116 insertions, 19 deletions
| diff --git a/server/src/config.rs b/server/src/config.rs index 5ef6c69..124e160 100644 --- a/server/src/config.rs +++ b/server/src/config.rs @@ -28,4 +28,5 @@ pub struct AppearanceConfig {      pub accent_dark: String,      pub background: String,      pub background_dark: String, +    pub background_light: String,  } diff --git a/server/src/logic.rs b/server/src/logic.rs index a69ca79..d474b79 100644 --- a/server/src/logic.rs +++ b/server/src/logic.rs @@ -28,16 +28,19 @@ pub struct Client(u64);  pub struct State {      idgen: IdGenerator,      rooms: RwLock<HashMap<String, Arc<Room>>>, +    watches: RwLock<HashMap<String, HashSet<Client>>>,  } -#[derive(Debug, Default)] +#[derive(Debug)]  pub struct Room { +    pub hash: String,      pub users: RwLock<HashSet<Client>>,  }  #[derive(Debug, Default)]  pub struct ClientState {      current_room: Option<Arc<Room>>, +    watches: Vec<String>,  }  impl State { @@ -79,9 +82,22 @@ impl State {          }          if let Some(room) = cstate.current_room { -            room.leave(client).await; +            room.leave(self, client).await;              // TODO dont leak room          } +        { +            let mut w = self.watches.write().await; +            for e in cstate.watches { +                let mut remove = false; +                if let Some(e) = w.get_mut(&e) { +                    e.remove(&client); +                    remove = e.is_empty() +                } +                if remove { +                    w.remove(&e); +                } +            } +        }      }      async fn on_recv(&self, client: Client, cstate: &mut ClientState, packet: ServerboundPacket) { @@ -89,15 +105,21 @@ impl State {              ServerboundPacket::Ping => (),              ServerboundPacket::Join { hash } => {                  if let Some(room) = &cstate.current_room { -                    room.leave(client).await; +                    room.leave(self, client).await;                      // TODO dont leak room                      // if room.should_remove().await {                      //     self.rooms.write().await.remove(üw);                      // }                  }                  if let Some(hash) = hash { -                    let room = self.rooms.write().await.entry(hash).or_default().clone(); -                    room.join(client).await; +                    let room = self +                        .rooms +                        .write() +                        .await +                        .entry(hash.clone()) +                        .or_insert_with(|| Room::new(&hash).into()) +                        .clone(); +                    room.join(self, client).await;                      cstate.current_room = Some(room.clone())                  } else {                      cstate.current_room = None @@ -116,7 +138,33 @@ impl State {                      }                  }              } -            ServerboundPacket::WatchRooms(_) => todo!(), +            ServerboundPacket::WatchRooms(mut list) => { +                let mut w = self.watches.write().await; +                let r = self.rooms.read().await; + +                for e in list.to_owned() { +                    w.entry(e.to_string()).or_default().insert(client); +                    if let Some(r) = r.get(&e) { +                        client +                            .send(ClientboundPacket::RoomInfo { +                                hash: e, +                                user_count: r.users.read().await.len(), +                            }) +                            .await; +                    } +                } +                std::mem::swap(&mut cstate.watches, &mut list); +                for e in list { +                    let mut remove = false; +                    if let Some(e) = w.get_mut(&e) { +                        e.remove(&client); +                        remove = e.is_empty() +                    } +                    if remove { +                        w.remove(&e); +                    } +                } +            }          }      }  } @@ -132,21 +180,47 @@ impl Client {  }  impl Room { -    pub async fn join(&self, client: Client) { +    pub fn new(hash: &String) -> Self { +        Self { +            hash: hash.to_owned(), +            users: Default::default(), +        } +    } +    pub async fn join(&self, state: &State, client: Client) {          debug!("client join {client:?}"); -        self.users.write().await.insert(client); +        let user_count = { +            let mut g = self.users.write().await; +            g.insert(client); +            g.len() +        }; +        for w in state +            .watches +            .read() +            .await +            .get(&self.hash) +            .into_iter() +            .flatten() +        { +            w.send(ClientboundPacket::RoomInfo { +                hash: self.hash.to_owned(), +                user_count, +            }) +            .await; +        }          // send join of this client to all clients -        self.broadcast(Some(client), ClientboundPacket::ClientJoin { id: client }) +        self.broadcast(None, ClientboundPacket::ClientJoin { id: client })              .await;          // send join of all other clients to this one          for rc in self.users.read().await.iter() { -            self.send_to_client(client, ClientboundPacket::ClientJoin { id: *rc }) -                .await; +            if *rc != client { +                self.send_to_client(client, ClientboundPacket::ClientJoin { id: *rc }) +                    .await; +            }          }      } -    pub async fn leave(&self, client: Client) { +    pub async fn leave(&self, state: &State, client: Client) {          debug!("client leave {client:?}");          for c in self.users.read().await.iter() {              if *c != client { @@ -154,7 +228,25 @@ impl Room {                      .await;              }          } -        self.users.write().await.remove(&client); +        let user_count = { +            let mut g = self.users.write().await; +            g.remove(&client); +            g.len() +        }; +        for w in state +            .watches +            .read() +            .await +            .get(&self.hash) +            .into_iter() +            .flatten() +        { +            w.send(ClientboundPacket::RoomInfo { +                hash: self.hash.to_owned(), +                user_count, +            }) +            .await; +        }          self.broadcast(Some(client), ClientboundPacket::ClientLeave { id: client })              .await;      } diff --git a/server/src/main.rs b/server/src/main.rs index 9ea0f94..f251e4e 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -6,10 +6,11 @@  #![feature(lazy_cell)]  pub mod assets;  pub mod config; +pub mod idgen;  pub mod logic;  pub mod protocol; -pub mod idgen; +use crate::protocol::ClientboundPacket;  use assets::css;  use config::{AppearanceConfig, Config};  use futures_util::{SinkExt, StreamExt, TryFutureExt}; @@ -22,11 +23,12 @@ use std::net::SocketAddr;  use std::str::FromStr;  use std::sync::Arc;  use tokio::sync::mpsc; -use warp::hyper::Server; -use warp::ws::WebSocket; -use warp::{reply, ws::Message, Filter, Rejection, Reply}; - -use crate::protocol::ClientboundPacket; +use warp::{ +    hyper::Server, +    reply, +    ws::{Message, WebSocket}, +    Filter, Rejection, Reply, +};  fn main() {      tokio::runtime::Builder::new_multi_thread() @@ -164,12 +166,14 @@ fn css_overrides(          accent_dark,          background,          background_dark, +        background_light,      }: &AppearanceConfig,  ) -> String {      format!(          r#":root {{  --bg: {background};  --bg-dark: {background_dark}; +--bg-light: {background_light};  --ac: {accent};  --ac-dark: {accent_dark};  --ac-dark-transparent: {accent_dark}c9; | 
