client broken (see TODO) but server pretty much complete

This commit is contained in:
Phuntsok Drak-pa 2018-03-23 00:30:55 +01:00
parent 48e5c2825d
commit 4d51fef365
3 changed files with 181 additions and 36 deletions

View File

@ -10,9 +10,31 @@ use std::hash::{Hash, Hasher};
use self::colored::*;
use self::chrono::Local;
/*
0.1 [ ]
1.1 [ ]
1.2 [ ]
1.3 [ ]
1.4 [ ]
1.5 [ ]
1.6 [ ]
1.7 [X]
1.8 [X]
1.9 [ ]
2.1 [X]
2.2 [X]
3.1 [ ] // pas utile avec Rust
3.2 [X]
4.1.1 [X]
4.1.2 [X]
4.2.1 [X]
4.2.2 [-]
*/
// TODO: Implement requests 1.x from protocol (connection currently is broken)
// TODO: Limit usernames to ascii
// TODO: Implement requests 1.x from protocol
// TODO: forbid usernames already in use
fn hash_name(name: &str) -> usize {
let mut s = DefaultHasher::new();

View File

@ -2,6 +2,8 @@
#![feature(stmt_expr_attributes)]
use std::env;
static PROTOCOL: &'static str = "0.1";
pub mod client;
pub mod server;

View File

@ -15,15 +15,16 @@ use self::chrono::Local;
/*
1.1 [ ]
1.2 [ ]
1.3 [ ]
1.4 [ ]
1.5 [ ]
1.6 [ ]
0.1 [X]
1.1 [X]
1.2 [X]
1.3 [X]
1.4 [X]
1.5 [X]
1.6 [X]
1.7 [X]
1.8 [X]
1.9 [ ]
1.9 [X]
2.1 [X]
2.2 [X]
3.1 [ ] // pas utile avec Rust
@ -163,23 +164,106 @@ fn handle_client(stream: TcpStream, clients: Arc<Mutex<UserMap>>) {
})
}
// Initialization: Ask user for his name
let name = match (|| {
send!("Welcome!");
send!("Please enter your name:");
let name = receive!();
println!("{} Client {} identified as {}", get_time(), client, name);
Ok(name)
// // Initialization: Ask user for his name
// let name = match (|| {
// send!("Welcome!");
// send!("Please enter your name:");
// let name = receive!();
// println!("{} Client {} identified as {}", get_time(), client, name);
// Ok(name)
// })()
// {
// Ok(name) => name,
// Err(e) => {
// println!(
// "{} Client {} disappeared during initialization: {}",
// get_time(),
// client,
// e
// );
// return ();
// }
// };
let name: String = match (|| loop {
match receive!() {
input => {
let spliced_input: Vec<&str> = input.split_whitespace().collect();
if spliced_input.len() != 4 && spliced_input.len() != 5
|| spliced_input[0] != "PROT"
{
// send!("BAD REQ");
return Err(Error::new(ErrorKind::Other, "BAD REQ"));
}
if spliced_input[1] != ::PROTOCOL {
// send!("BAD PROT");
return Err(Error::new(ErrorKind::Other, "BAD PROT"));
}
if spliced_input.len() == 5 {
if spliced_input[2] == "CONNECT" && spliced_input[3] == "USER" {
let username = String::from(spliced_input[4]);
let mut used = false;
{
let lock = clients.lock().unwrap();
for (_, entry) in (*lock).iter() {
if username == entry.0 {
used = true;
break;
}
}
}
if used == false {
send!("NAME OK");
return Ok(username);
} else {
send!("NAME FAILURE");
}
}
}
loop {
send!("NAME REQ");
match receive!() {
input => {
let spliced_input: Vec<&str> = input.split_whitespace().collect();
if spliced_input.len() != 2 || spliced_input[0] != "NAME" {
return Err(Error::new(ErrorKind::Other, "BAD REQ"));
}
let username = String::from(spliced_input[1]);
let mut used = false;
{
let lock = clients.lock().unwrap();
for (_, entry) in (*lock).iter() {
if username == entry.0 {
used = true;
break;
}
}
}
if used == false {
send!("NAME OK");
return Ok(username);
} else {
send!("NAME FAILURE");
}
}
}
}
// return Ok(String::new());
}
}
})()
{
Ok(name) => name,
Err(e) => {
println!(
"{} Client {} disappeared during initialization: {}",
get_time(),
client,
e
"{time} Client {addr} encountered an error: {err}",
time = get_time(),
addr = client,
err = e
);
writeln!(writer, "{}", e).unwrap();
writer.flush().unwrap();
return ();
}
};
@ -194,26 +278,63 @@ fn handle_client(stream: TcpStream, clients: Arc<Mutex<UserMap>>) {
writeln!(writer, "WELCOME").unwrap();
writer.flush().unwrap();
// Chat loop: Receive messages from users
// Chat loop: Receive messages from users once connected
match (|| loop {
match receive!().as_str() {
"BYE" => {
send!("BYE");
return Ok(());
}
"PING" => {
send!("PONG");
}
"REQ CLIENTS" => {
let mut lock = clients.lock().unwrap();
send_clients_name(&client, &mut lock);
}
input => {
println!("{} {} <{}>: {}", get_time(), client, name, input);
{
let mut lock = clients.lock().unwrap();
distribute_message(&format!("{}", input), &client, &mut lock, true);
println!(
"{time} {nick}@{addr}: {message}",
time = get_time(),
addr = client,
nick = name,
message = input
);
match input {
"BYE" => {
send!("BYE");
return Ok(());
}
"PING" => send!("PONG"),
"REQ CLIENTS" => {
let mut lock = clients.lock().unwrap();
send_clients_name(&client, &mut lock);
}
input => {
let spliced_input: Vec<&str> = input.split_whitespace().collect();
match spliced_input[0] {
"MSG" => {
let mut message = String::new();
for i in 1..spliced_input.len() {
message.push_str(spliced_input[i]);
}
{
let mut lock = clients.lock().unwrap();
distribute_message(
&format!("{}", input),
&client,
&mut lock,
true,
);
}
}
_ => {
println!(
"{time} Sending: BAD REQ. Cause: {message}",
time = get_time(),
message = input
);
send!("BAD REQ");
}
}
}
}
// {
// let mut lock = clients.lock().unwrap();
// distribute_message(&format!("{}", input), &client, &mut lock, true);
// }
}
}
})()