@@ -9,10 +9,9 @@ use uuid::Uuid;
99pub type ClientMap = DashMap < ClientId , RoomId > ;
1010pub type RoomMap = DashMap < RoomId , Room > ;
1111
12- /// Maximum number of log lines retained in each log (both per-room and system logs)
13- /// Oldest lines are dropped once the buffer is full.
1412const VALID_ROOM_ID_CHARACTERS : [ char ; 36 ] = valid_room_id_characters ( ) ;
1513const MAX_ROOM_COUNT : usize = 32 ;
14+ const MAX_MEMBER_COUNT_PER_ROOM : usize = 10 ;
1615
1716pub struct State {
1817 pub users : ClientMap ,
@@ -34,7 +33,7 @@ impl State {
3433 name : & str ,
3534 ) -> Option < ( ClientId , RoomId ) > {
3635 match room_id {
37- None if self . room_count ( ) = = MAX_ROOM_COUNT => None ,
36+ None if self . room_count ( ) > = MAX_ROOM_COUNT => None ,
3837 None => Some ( self . add_room_and_host ( name, tx) ) ,
3938 Some ( room_id) => self
4039 . add_client_to_room ( name, tx, & room_id)
@@ -66,13 +65,15 @@ impl State {
6665 ( host_id, room_id)
6766 }
6867
69- /// # Safety
68+ /// # Deadlock
7069 /// Relinquish all locks on `self.room` before calling
7170 pub fn remove_client ( & self , client_id : & ClientId ) {
7271 let Some ( room_id) = self . users . get ( client_id) . map ( |a| a. value ( ) . clone ( ) ) else {
7372 return ;
7473 } ;
7574
75+ self . users . remove ( client_id) ;
76+
7677 // Room lock held
7778 let Some ( mut room) = self . rooms . get_mut ( & room_id) else {
7879 return ;
@@ -94,6 +95,7 @@ impl State {
9495 room_id : & RoomId ,
9596 ) -> Option < ClientId > {
9697 let client_id = Uuid :: new_v4 ( ) ;
98+
9799 let Some ( mut room) = self . rooms . get_mut ( room_id) else {
98100 warn_global ! ( "Attempted to add {client_id} into non-existant room {room_id}" ) ;
99101 return None ;
@@ -103,6 +105,10 @@ impl State {
103105 return None ;
104106 }
105107
108+ if room. members . len ( ) >= MAX_MEMBER_COUNT_PER_ROOM {
109+ return None ;
110+ }
111+
106112 let client = Client :: new ( client_id, client_name. to_string ( ) , client_tx) ;
107113 room. members . push ( client) ;
108114 self . users . insert ( client_id, room_id. clone ( ) ) ;
@@ -125,13 +131,18 @@ impl State {
125131 return ;
126132 }
127133
134+ if self . rooms . contains_key ( room_id) {
135+ error_global ! ( "Attempted to create permanent room that already exists" ) ;
136+ return ;
137+ }
138+
128139 let room = Room {
129140 members : Vec :: new ( ) ,
130141 host : None ,
131142 locked : false ,
132143 permanent : true ,
133144 } ;
134- self . rooms . insert ( room_id. to_string ( ) , room) ;
145+ self . rooms . insert ( room_id. clone ( ) , room) ;
135146 }
136147
137148 pub fn get_room_of_client_mut ( & self , client_id : & ClientId ) -> Option < RefMut < ' _ , RoomId , Room > > {
@@ -149,12 +160,12 @@ impl State {
149160 self . rooms . get ( & room_id)
150161 }
151162
152- pub fn get_senders_from_user_room ( & self , client_id : ClientId ) -> Vec < ClientSender > {
153- let Some ( room) = self . get_room_of_client ( & client_id) else {
163+ pub fn get_senders_from_user_room ( & self , client_id : & ClientId ) -> Vec < ClientSender > {
164+ let Some ( room) = self . get_room_of_client ( client_id) else {
154165 return Vec :: new ( ) ;
155166 } ;
156167
157- room. get_peer_senders ( & client_id)
168+ room. get_peer_senders ( client_id)
158169 }
159170
160171 /// Flips whether new clients can join `room_id`.
@@ -222,9 +233,14 @@ impl State {
222233}
223234
224235pub fn is_valid_room_id ( s : & str ) -> bool {
225- s. trim ( ) . len ( ) == 6
226- && s. chars ( )
227- . all ( |c| c. is_ascii_digit ( ) || c. is_ascii_uppercase ( ) )
236+ let s = s. trim ( ) ;
237+
238+ let correct_length = s. len ( ) == 6 ;
239+ let all_characters_valid = s
240+ . chars ( )
241+ . all ( |c| c. is_ascii_digit ( ) || c. is_ascii_uppercase ( ) ) ;
242+
243+ correct_length && all_characters_valid
228244}
229245
230246const fn valid_room_id_characters ( ) -> [ char ; 36 ] {
0 commit comments