diff --git a/src/main.rs b/src/main.rs index 69eb24b..730adbe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,9 @@ -use chrono::{DateTime, Local, Duration}; -use std::{ - collections::{HashMap, HashSet}, - net::UdpSocket, -}; +use chrono::{DateTime, Duration, Local}; +use std::{collections::HashMap, net::UdpSocket}; const MAX_CLIENTS: usize = 10; const CLIENT_TIMEOUT: u32 = 300; -const MY_SPEED: u8 = 20; - -#[derive(Hash, Eq, PartialEq, Debug, Clone)] -struct Client { - name: String, - time: DateTime, -} +const MY_SPEED: u8 = 30; fn strip_header(msg: &[u8]) -> Vec { //print_msg(msg); @@ -111,64 +102,76 @@ fn mopp(speed: u8, data: &[u8]) -> Vec { res.to_owned() } -fn broadcast(socket: &UdpSocket, receivers: &HashSet, client: &Client, data: &[u8]) { +fn broadcast( + socket: &UdpSocket, + receivers: &HashMap>, + client: &str, + data: &[u8], +) { for rec in receivers { // Do not broadcast to origin - if rec.name == client.name { + if rec.0 == client { continue; } - socket.send_to(&data, &rec.name).unwrap(); + socket.send_to(&data, &rec.0).unwrap(); } } fn main() -> std::io::Result<()> { - let socket = UdpSocket::bind("0.0.0.0:7373")?; socket .set_read_timeout(None) .expect("Could not set read timeout"); - let mut receivers: HashSet = HashSet::new(); + let mut receivers2: HashMap> = HashMap::new(); loop { let mut buf = [0; 64]; let (number_of_bytes, src_addr) = socket.recv_from(&mut buf).expect("Didn't receive data"); let client_addr = src_addr.to_string(); - let client = Client { - name: client_addr.clone(), - time: Local::now(), - }; let speed = buf[1] >> 2; - let data = &buf[0..number_of_bytes]; - if receivers.iter().any(|x| x.name == client_addr) { + if receivers2.contains_key(&client_addr) { //println!("Client already known."); - broadcast(&socket, &receivers, &client, data); + if strip_header(data) == strip_header(mopp(speed, b":bye").as_slice()) { + println!("TSCHAU"); + socket + .send_to(mopp(speed, b":bye").as_slice(), &client_addr) + .unwrap(); + receivers2.remove(&client_addr); + } else { + broadcast(&socket, &receivers2, &client_addr, data); + receivers2.insert(client_addr.to_owned(), Local::now()); + } } else if strip_header(data) == strip_header(mopp(speed, b"hi").as_slice()) { //println!("Welcome!"); - if receivers.len() < MAX_CLIENTS { - receivers.insert(client.clone()); + if receivers2.len() < MAX_CLIENTS { + receivers2.insert(client_addr.to_owned(), Local::now()); socket - .send_to(mopp(MY_SPEED, b"hi").as_slice(), &client.name) + .send_to( + mopp(speed, format!("{}{}", ":hi ", receivers2.len()).as_bytes()) + .as_slice(), + &client_addr, + ) .unwrap(); } else { socket - .send_to(mopp(MY_SPEED, b":qrl").as_slice(), &client.name) + .send_to(mopp(speed, b":qrl").as_slice(), &client_addr) .unwrap(); } } else { //println!("Unknown client - Ignoring"); } - let timestamp = Local::now(); - for cl in &receivers { - if cl.time + Duration::seconds(CLIENT_TIMEOUT as i64) < timestamp { + let timestamp = Local::now(); + for cl in &receivers2 { + if *cl.1 + Duration::seconds(CLIENT_TIMEOUT as i64) < timestamp { socket - .send_to(mopp(MY_SPEED, b":bye").as_slice(), &client.name) + .send_to(mopp(MY_SPEED, b":bye").as_slice(), &client_addr) .unwrap(); } } - receivers.retain(|cl| cl.time + Duration::seconds(CLIENT_TIMEOUT as i64) >= timestamp); + receivers2.retain(|_, val| *val + Duration::seconds(CLIENT_TIMEOUT as i64) >= timestamp); } }