From ac1eecd9e5e714fe04fe7b4540c83e21f4f16f34 Mon Sep 17 00:00:00 2001 From: David Westgate Date: Thu, 30 Nov 2023 01:03:05 -0800 Subject: [PATCH] add error handling for sending message when not in the room --- src/client.rs | 18 +++++++++++++----- src/lib.rs | 1 + src/server.rs | 36 +++++++++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/client.rs b/src/client.rs index 0fd6714..251b8c6 100644 --- a/src/client.rs +++ b/src/client.rs @@ -64,16 +64,19 @@ fn process_message(msg_bytes: &[u8], nick: &str) { match msg_bytes[0] { codes::ERROR => match msg_bytes[1] { codes::error::INVALID_ROOM => { - println!("Operation Performed on an invalid room. Try again"); + eprintln!("Operation Performed on an invalid room. Try again"); } codes::error::NICKNAME_COLLISION => { - println!("Nickname already in use on server. Connect again with a different one"); + eprintln!("Nickname already in use on server. Connect again with a different one"); } codes::error::SERVER_FULL => { - println!("Server is full. Try again later"); + eprintln!("Server is full. Try again later"); + } + codes::error::NOT_IN_ROOM => { + eprintln!("Cannot send a message before joining room. Use /join [room].") } _ => { - println!("Error code: {:x?}", msg_bytes[1]); + eprintln!("Error code: {:x?}", msg_bytes[1]); } }, @@ -171,7 +174,12 @@ pub fn start() { one_param_op(codes::client::REGISTER_NICK, &mut stream, &nick); loop { - let inp: String = input!("\n[{}]:", active_room); + let mut inp = String::new(); + if active_room.is_empty() { + inp = input!(""); + } else { + inp = input!("\n[{}]:", active_room); + } let mut args: std::str::SplitWhitespace<'_> = inp.split_whitespace(); let command: Option<&str> = args.next(); diff --git a/src/lib.rs b/src/lib.rs index 6ba14b8..f1e1cc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,6 +25,7 @@ pub mod codes { pub const NOT_YET_REGISTERED: u8 = 0x14; pub const MALFORMED: u8 = 0x15; pub const ALREADY_IN_ROOM: u8 = 0x16; + pub const NOT_IN_ROOM: u8 = 0x17; } } diff --git a/src/server.rs b/src/server.rs index 8ef3a2b..3888e59 100644 --- a/src/server.rs +++ b/src/server.rs @@ -84,7 +84,7 @@ fn message(room: &str, msg: &str, sender: &str, server: &Arc>) { } fn broadcast(op: u8, server: &Arc>, message: &str) { - let size = message.len() + 1; + let size: usize = message.len() + 1; let mut out_buf: Vec = vec![0; size]; out_buf[0] = op; @@ -191,7 +191,29 @@ fn handle_client( let params: Option<(&str, &str)> = p.split_once(" "); match params { Some((room, msg)) => { - message(room, msg, nickname, server); + let unlocked_server: std::sync::MutexGuard<'_, Server> = server.lock().unwrap(); + let users_in_room: Option<&Vec> = unlocked_server.rooms.get(room); + match users_in_room { + Some(users) => { + let is_user_in_room: Option<&String> = + users.iter().find(|&u| u.eq(nickname)); + match is_user_in_room { + Some(_) => { + message(room, msg, nickname, server); + } + None => { + stream + .write_all(&[codes::ERROR, codes::error::NOT_IN_ROOM]) + .unwrap(); + } + } + } + None => { + stream + .write_all(&[codes::ERROR, codes::error::INVALID_ROOM]) + .unwrap(); + } + } } _ => { stream @@ -217,7 +239,7 @@ fn remove_user(server: &Arc>, nickname: &str, stream: &mut TcpStre let server: &mut Server = guard.deref_mut(); let mut rooms: &mut HashMap> = &mut server.rooms; rooms.values_mut().for_each(|room: &mut Vec| { - room.retain(|u| !u.eq(nickname)); + room.retain(|u: &String| !u.eq(nickname)); }); let users: &mut HashMap = &mut server.users; users.remove(nickname); @@ -234,8 +256,8 @@ fn register_nick(server: &Arc>, nickname: &str, stream: &mut TcpSt .unwrap(); } else { // Add the user to the user list - let clone = stream.try_clone().expect("fail to clone"); - let addr = clone.peer_addr().unwrap().to_string(); + let clone: TcpStream = stream.try_clone().expect("fail to clone"); + let addr: String = clone.peer_addr().unwrap().to_string(); unlocked_server.users.insert(nickname.to_string(), clone); // Send response ok @@ -391,8 +413,8 @@ pub fn start() { 1 => println!("Users: {:?}", server.lock().unwrap().users), 2 => println!("Rooms: {:?}", server.lock().unwrap().rooms), 3 => { - let inp = input!("Enter message: "); - broadcast(codes::client::MESSAGE, &server, &inp) + let inp2 = input!("Enter message: "); + broadcast(codes::client::MESSAGE, &server, &inp2); } _ => println!("Invalid Input"), },