diff --git a/src/client.rs b/src/client.rs index be23806..0fd6714 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,5 @@ use prompted::input; -use rust_irc::{codes, clear}; +use rust_irc::{clear, codes}; use std::io::{Read, Write}; use std::net::TcpStream; use std::thread; @@ -11,7 +11,7 @@ fn no_param_op(opcode: u8, stream: &mut TcpStream) { } fn one_param_op(opcode: u8, stream: &mut TcpStream, param: &str) { - let size = param.to_string().capacity() + 1; + let size: usize = param.to_string().capacity() + 1; let mut out_buf: Vec = vec![0; size]; out_buf[0] = opcode; @@ -22,7 +22,7 @@ fn one_param_op(opcode: u8, stream: &mut TcpStream, param: &str) { } fn two_param_op(opcode: u8, stream: &mut TcpStream, param0: &str, param1: &str) { - let size = param0.to_string().capacity() + param1.to_string().capacity() + 2; + let size: usize = param0.to_string().capacity() + param1.to_string().capacity() + 2; let mut out_buf: Vec = vec![0; size]; let mut byte: usize = 0; out_buf[byte] = opcode; @@ -44,10 +44,11 @@ fn read_messages(mut stream: TcpStream, nick: &str) { let mut buffer: [u8; 1024] = [0; 1024]; loop { match stream.read(&mut buffer) { + Ok(0) => { + println!("Server closed the connection. Shutting down client"); + std::process::exit(0); + } Ok(size) => { - if size == 0 { - break; //Server closed connection - } let msg_bytes: &[u8] = &buffer[..size]; process_message(msg_bytes, nick); } @@ -61,29 +62,24 @@ fn read_messages(mut stream: TcpStream, nick: &str) { fn process_message(msg_bytes: &[u8], nick: &str) { println!(); match msg_bytes[0] { - codes::ERROR => - { - match msg_bytes[1] { - codes::error::INVALID_ROOM => { - println!("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" - ); - } - codes::error::SERVER_FULL => { - println!("Server is full. Try again later"); - } - _ => { - println!("Error code: {:x?}", msg_bytes[1]); - } + codes::ERROR => match msg_bytes[1] { + codes::error::INVALID_ROOM => { + println!("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"); + } + codes::error::SERVER_FULL => { + println!("Server is full. Try again later"); + } + _ => { + println!("Error code: {:x?}", msg_bytes[1]); + } + }, codes::client::MESSAGE => { let message = String::from_utf8(msg_bytes[1..msg_bytes.len()].to_vec()).unwrap(); - println!("{}", message); + println!("[server]:{}", message); } codes::client::MESSAGE_ROOM => { let params = String::from_utf8(msg_bytes[1..msg_bytes.len()].to_vec()).unwrap(); @@ -151,9 +147,7 @@ pub fn start() { nick = input!("Enter your nickname : "); if nick.contains(" ") { println!("May not contain spaces . Try again"); - - } - else if nick.is_empty() { + } else if nick.is_empty() { println!("May not be empty . Try again"); } else { break; @@ -168,7 +162,7 @@ pub fn start() { //another stream for reading messages let stream_clone: TcpStream = stream.try_clone().expect("Failed to clone stream"); - let nick_clone = nick.clone(); + let nick_clone: String = nick.clone(); thread::spawn(move || { read_messages(stream_clone, &nick_clone); }); @@ -177,7 +171,7 @@ pub fn start() { one_param_op(codes::client::REGISTER_NICK, &mut stream, &nick); loop { - let inp: String = input!("\n[{}]:",active_room); + let inp: String = input!("\n[{}]:", active_room); let mut args: std::str::SplitWhitespace<'_> = inp.split_whitespace(); let command: Option<&str> = args.next(); @@ -185,7 +179,10 @@ pub fn start() { Some(cmd) => { let param: Option<&str> = args.next(); match cmd { - "/quit" => {disconnect(&mut stream); break}, + "/quit" => { + disconnect(&mut stream); + break; + } "/rooms" => no_param_op(codes::client::LIST_ROOMS, &mut stream), "/users" => no_param_op(codes::client::LIST_USERS, &mut stream), "/list" => match param { diff --git a/src/server.rs b/src/server.rs index cb8250f..8ef3a2b 100644 --- a/src/server.rs +++ b/src/server.rs @@ -8,7 +8,7 @@ use std::{ }; use prompted::input; -use rust_irc::{codes, clear}; +use rust_irc::{clear, codes}; const SERVER_ADDRESS: &str = "0.0.0.0:6667"; const MAX_USERS: usize = 20; @@ -28,7 +28,6 @@ impl Server { } } - fn message(room: &str, msg: &str, sender: &str, server: &Arc>) { let size = room.len() + msg.len() + sender.len() + 3; let mut out_buf: Vec = vec![0; size]; @@ -71,15 +70,15 @@ fn message(room: &str, msg: &str, sender: &str, server: &Arc>) { str.write_all(&out_buf).unwrap(); } None => { + //TODO send error msg to sender eprintln!("Error: Invalid message from client"); - } } } } None => { + //TODO send error msg to sender eprintln!("Error: Invalid message from client"); - } } } @@ -94,20 +93,21 @@ fn broadcast(op: u8, server: &Arc>, message: &str) { } let mut unlocked_server: std::sync::MutexGuard<'_, Server> = server.lock().unwrap(); - let streams: std::collections::hash_map::ValuesMut<'_, String, TcpStream> = unlocked_server.users.values_mut(); + let streams: std::collections::hash_map::ValuesMut<'_, String, TcpStream> = + unlocked_server.users.values_mut(); for stream in streams { stream.write_all(&out_buf).unwrap(); } } -fn disconnect_all(server: &Arc>,) { +fn disconnect_all(server: &Arc>) { let mut guard: std::sync::MutexGuard<'_, Server> = server.lock().unwrap(); - let users: std::collections::hash_map::ValuesMut<'_, String, TcpStream> = guard.users.values_mut(); - users.for_each(|user: &mut TcpStream| { + let users: std::collections::hash_map::ValuesMut<'_, String, TcpStream> = + guard.users.values_mut(); + users.for_each(|user: &mut TcpStream| { user.write(&[codes::QUIT]).unwrap(); - user.shutdown(std::net::Shutdown::Both); + user.shutdown(std::net::Shutdown::Both).unwrap(); }) - } fn handle_client( @@ -188,8 +188,6 @@ fn handle_client( codes::client::MESSAGE_ROOM => { let p: String = String::from_utf8_lossy(param_bytes).to_string(); - #[cfg(debug_assertions)] - println!("MESSAGE_ROOM, {:?} ", p); let params: Option<(&str, &str)> = p.split_once(" "); match params { Some((room, msg)) => { @@ -203,7 +201,7 @@ fn handle_client( } } codes::QUIT => { - remove_user(server, nickname,stream); + remove_user(server, nickname, stream); } _ => { #[cfg(debug_assertions)] @@ -221,9 +219,8 @@ fn remove_user(server: &Arc>, nickname: &str, stream: &mut TcpStre rooms.values_mut().for_each(|room: &mut Vec| { room.retain(|u| !u.eq(nickname)); }); - let users: &mut HashMap = &mut server.users; + let users: &mut HashMap = &mut server.users; users.remove(nickname); - } fn register_nick(server: &Arc>, nickname: &str, stream: &mut TcpStream) { @@ -243,7 +240,7 @@ fn register_nick(server: &Arc>, nickname: &str, stream: &mut TcpSt unlocked_server.users.insert(nickname.to_string(), clone); // Send response ok stream.write_all(&[codes::RESPONSE_OK]).unwrap(); - + println!("{} has registered nickname {}", addr, nickname); } } @@ -275,8 +272,8 @@ fn leave_room(server: &Arc>, user: &str, room: &str, stream: &mut let mut unlocked_server: std::sync::MutexGuard<'_, Server> = server.lock().unwrap(); match unlocked_server.rooms.get_mut(room) { Some(l) => { - let before_len = l.len(); - l.retain(|item| item != user); + let before_len: usize = l.len(); + l.retain(|item: &String| item != user); if l.len() == 0 { unlocked_server.rooms.remove(room); stream.write_all(&[codes::RESPONSE_OK]).unwrap(); @@ -312,10 +309,16 @@ pub fn start() { thread::spawn(move || { let nickname: String; - println!("IP {} has connected", stream.peer_addr().unwrap().to_string()); + println!( + "IP {} has connected", + stream.peer_addr().unwrap().to_string() + ); match stream.read(&mut buf_in) { Ok(0) => { - println!("IP {} has closed the connection", stream.peer_addr().unwrap().to_string()); + println!( + "IP {} has closed the connection", + stream.peer_addr().unwrap().to_string() + ); } Ok(size) => { let cmd_bytes: &[u8] = &buf_in[0..1]; @@ -326,7 +329,8 @@ pub fn start() { loop { match stream.read(&mut buf_in) { Ok(0) => { - println!("IP {} wit nickname {} has closed the connection", stream.peer_addr().unwrap().to_string(), nickname); + println!("IP {} with nickname {} has closed the connection", stream.peer_addr().unwrap().to_string(), nickname); + remove_user(&server_inner, &nickname, &mut stream); break; } Ok(size) => { @@ -383,7 +387,6 @@ pub fn start() { println!("Stopping Server"); disconnect_all(&server); break; - } 1 => println!("Users: {:?}", server.lock().unwrap().users), 2 => println!("Rooms: {:?}", server.lock().unwrap().rooms),