From d5935cdfff04d51136bbfdcbaf6a7352be4d61e8 Mon Sep 17 00:00:00 2001 From: David Westgate Date: Thu, 30 Nov 2023 19:00:03 -0800 Subject: [PATCH] support leave/join messages --- src/client.rs | 3 +++ src/server.rs | 46 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/client.rs b/src/client.rs index 065c792..b7b3e7f 100644 --- a/src/client.rs +++ b/src/client.rs @@ -79,6 +79,9 @@ fn process_message(msg_bytes: &[u8], nick: &str) { codes::error::EMPTY_ROOM => { eprintln!("Room is Empty"); } + codes::error::ALREADY_IN_ROOM => { + eprintln!("You are already in that room"); + } _ => { eprintln!("Error code: {:x?}", msg_bytes[1]); } diff --git a/src/server.rs b/src/server.rs index 3be05f4..e2bf4fe 100644 --- a/src/server.rs +++ b/src/server.rs @@ -220,7 +220,6 @@ fn handle_client( } codes::KEEP_ALIVE => { - println!("kEEP alive"); stream.write_all(&[codes::RESPONSE_OK]).unwrap(); } @@ -304,7 +303,14 @@ fn join_room(server: &Arc>, user: &str, room: &str, stream: &mut T unlocked_server.rooms.insert(room.to_string(), list); } } - stream.write_all(&[codes::RESPONSE_OK]).unwrap(); + drop(unlocked_server); + let rooms: Vec = get_rooms_of_user(server, user); + let rooms_expanded: String = rooms.join(","); + let response: String = format!("Joined {}. Current rooms: {}", room, rooms_expanded); + let res_bytes: &[u8] = response.as_bytes(); + let code_bytes: &[u8] = &[codes::RESPONSE]; + let out: &Vec = &[code_bytes, res_bytes].concat(); + stream.write_all(out).unwrap(); } fn leave_room(server: &Arc>, user: &str, room: &str, stream: &mut TcpStream) { @@ -315,13 +321,27 @@ fn leave_room(server: &Arc>, user: &str, room: &str, stream: &mut l.retain(|item: &String| item != user); if l.len() == 0 { unlocked_server.rooms.remove(room); - stream.write_all(&[codes::RESPONSE_OK]).unwrap(); + drop(unlocked_server); + let rooms: Vec = get_rooms_of_user(server, user); + let rooms_expanded: String = rooms.join(","); + let response: String = format!("Left {}. Current rooms: {}", room, rooms_expanded); + let code_bytes: &[u8] = &[codes::RESPONSE]; + let res_bytes: &[u8] = response.as_bytes(); + let out: &Vec = &[code_bytes, res_bytes].concat(); + stream.write_all(out).unwrap(); } else if l.len() == before_len { stream .write_all(&[codes::ERROR, codes::error::INVALID_ROOM]) .unwrap(); } else { - stream.write_all(&[codes::RESPONSE_OK]).unwrap(); + drop(unlocked_server); + let rooms: Vec = get_rooms_of_user(server, user); + let rooms_expanded: String = rooms.join(","); + let response: String = format!("Left {}. Current rooms: {}", room, rooms_expanded); + let code_bytes: &[u8] = &[codes::RESPONSE]; + let res_bytes: &[u8] = response.as_bytes(); + let out: &Vec = &[code_bytes, res_bytes].concat(); + stream.write_all(out).unwrap(); } } None => { @@ -332,6 +352,24 @@ fn leave_room(server: &Arc>, user: &str, room: &str, stream: &mut } } +// Iterate on all rooms, capture each room name which has the user +// return a vec of strings of room names +fn get_rooms_of_user(server: &Arc>, user: &str) -> Vec { + let mut result: Vec = vec![]; + let guard: std::sync::MutexGuard<'_, Server> = server.lock().unwrap(); + let rooms: std::collections::hash_map::Keys<'_, String, Vec> = guard.rooms.keys(); + rooms.for_each(|room| { + let user_vec = guard.rooms.get(room).unwrap(); + for usr in user_vec { + if usr.eq(user) { + result.push(room.to_string()); + break; + } + } + }); + result +} + pub fn start() { let listener: TcpListener = TcpListener::bind(SERVER_ADDRESS).expect("Failed to bind to port"); let server: Arc> = Arc::new(Mutex::new(Server::new()));