From a6681f31a07e1cb280de1d606f5656f1de3c2081 Mon Sep 17 00:00:00 2001 From: Adam <24621027+adoyle0@users.noreply.github.com> Date: Wed, 31 Jul 2024 21:19:29 -0400 Subject: [PATCH] on and offline users --- Cargo.lock | 33 +++++----- server/src/api.rs | 14 ++-- server/src/api/message_handler.rs | 103 ++++++++++++++++++++++++------ server/src/main.rs | 10 ++- 4 files changed, 117 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc610b2..9390da0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,9 +226,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" [[package]] name = "camino" @@ -838,9 +838,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown", @@ -1371,12 +1371,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.19" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2288c0e17cc8d342c712bb43a257a80ebffce59cdb33d5000d8348f3ec02528b" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" dependencies = [ "zerocopy", - "zerocopy-derive", ] [[package]] @@ -2057,9 +2056,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a44eede9b727419af8095cb2d72fab15487a541f54647ad4414b34096ee4631" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -2078,9 +2077,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.18" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1490595c74d930da779e944f5ba2ecdf538af67df1a9848cbd156af43c1b7cf0" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ "indexmap", "serde", @@ -2571,9 +2570,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.16" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -2592,9 +2591,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" dependencies = [ "byteorder", "zerocopy-derive", @@ -2602,9 +2601,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" dependencies = [ "proc-macro2", "quote", diff --git a/server/src/api.rs b/server/src/api.rs index 203fd50..a9ddc9c 100644 --- a/server/src/api.rs +++ b/server/src/api.rs @@ -27,7 +27,7 @@ fn motd() -> String { /// Generate server summary update - mostly debug stuff fn server_summary_update(state: &Arc) -> String { to_string::(&ServerStateSummary { - online_users: state.users.lock().unwrap().len(), + online_users: state.online_users.lock().unwrap().len(), active_games: state.games.lock().unwrap().len(), }) .unwrap() @@ -38,7 +38,7 @@ fn chat_meta_update(state: &Arc) -> String { // this may get expensive if there are many users let mut names = vec![]; - for user in state.users.lock().unwrap().iter() { + for user in state.online_users.lock().unwrap().iter() { names.push(user.1.name.clone()); } @@ -65,7 +65,7 @@ fn games_update(state: &Arc) -> String { fn announce_join(state: &Arc, addr: &SocketAddr) -> String { let msg = format!( "{} joined.", - state.users.lock().unwrap().get(addr).unwrap().name + state.online_users.lock().unwrap().get(addr).unwrap().name ); tracing::debug!("{}", &msg); @@ -98,7 +98,9 @@ async fn handle_new_user( addr: &SocketAddr, ) -> Result<()> { // Create - let new_user = generate_new_user(state); + let new_user = Box::pin(generate_new_user(state)); + tracing::debug!("User created at ptr: {:p}", new_user); + tracing::debug!("User borrowed ptr: {:p}", *&new_user); // Notify client of new username sender @@ -106,7 +108,9 @@ async fn handle_new_user( .await?; // Register using `addr` as key until something longer lived exists - state.users.lock().unwrap().insert(*addr, new_user); + state.online_users.lock().unwrap().insert(*addr, new_user); + tracing::debug!("New user inserted at ptr: {:p}", state.online_users.lock().unwrap().get(addr).unwrap()); + tracing::debug!("New user hashmap deref ptr: {:p}", *state.online_users.lock().unwrap().get(addr).unwrap()); // Hydrate client // this should probably be combined and sent as one diff --git a/server/src/api/message_handler.rs b/server/src/api/message_handler.rs index a7b17e9..410cc19 100644 --- a/server/src/api/message_handler.rs +++ b/server/src/api/message_handler.rs @@ -39,7 +39,7 @@ fn handle_chat_message( tx: &Sender, addr: SocketAddr, ) -> Result<()> { - let msg = format! {"{0}: {1}", state.users.lock().unwrap().get(&addr).unwrap().name, chat_message.text}; + let msg = format! {"{0}: {1}", state.online_users.lock().unwrap().get(&addr).unwrap().name, chat_message.text}; tracing::debug!("{msg}"); tx.send(to_string::(&ChatMessage { text: msg })?)?; @@ -53,25 +53,71 @@ fn handle_user_log_in( tx: &Sender, addr: SocketAddr, ) -> Result<()> { - let old_name = state.users.lock().unwrap().get(&addr).unwrap().name.clone(); - let new_name = user_log_in.username.clone(); - - state - .users + let old_name = state + .online_users .lock() .unwrap() - .get_mut(&addr) + .get(&addr) .unwrap() - .change_name(user_log_in.username); + .name + .clone(); + let new_name = user_log_in.username.clone(); - let msg = format! { - "{0} changed name to {1}.", - old_name, - new_name - }; + if state.offline_users.lock().unwrap().contains_key(&new_name) { + state + .online_users + .lock() + .unwrap() + .insert( + addr, + state + .offline_users + .lock() + .unwrap() + .remove(&new_name) + .unwrap(), + ) + .unwrap(); - tracing::debug!("{msg}"); - tx.send(to_string::(&ChatMessage { text: msg })?)?; + let msg = format! { + "{0} changed name to {1}. Welcome back!", + old_name, + new_name + }; + + tracing::debug!("{msg}"); + } else { + state + .online_users + .lock() + .unwrap() + .get_mut(&addr) + .unwrap() + .change_name(user_log_in.username); + + let msg = format! { + "{0} changed name to {1}.", + old_name, + new_name + }; + + tracing::debug!("{msg}"); + tx.send(to_string::(&ChatMessage { text: msg })?)?; + } + + tracing::debug!( + "User updated at ptr: {:p}", + state.online_users.lock().unwrap().get(&addr).unwrap() + ); + tracing::debug!( + "User updated deref ptr: {:p}", + *state.online_users.lock().unwrap().get(&addr).unwrap() + ); + tracing::debug!( + "Online Users: {} Offline Users: {}", + state.online_users.lock().unwrap().len(), + state.offline_users.lock().unwrap().len() + ); Ok(()) } @@ -86,7 +132,7 @@ fn handle_close( if let Some(cf) = close_frame { tracing::debug!( "Close received from {0} with code: {1} and reason: {2}", - state.users.lock().unwrap().get(&addr).unwrap().name, + state.online_users.lock().unwrap().get(&addr).unwrap().name, cf.code, cf.reason ) @@ -97,13 +143,34 @@ fn handle_close( let msg = ChatMessage { text: format!( "{0} left.", - state.users.lock().unwrap().get(&addr).unwrap().name + state.online_users.lock().unwrap().get(&addr).unwrap().name ), }; tracing::debug!("{}", msg.text); tx.send(to_string::(&msg)?)?; - state.users.lock().unwrap().remove(&addr).unwrap(); + let name = state + .online_users + .lock() + .unwrap() + .get(&addr) + .unwrap() + .name + .clone(); + + state.offline_users.lock().unwrap().insert( + name.clone(), + state.online_users.lock().unwrap().remove(&addr).unwrap(), + ); + + tracing::debug!( + "User moved to offline ptr: {:p}", + state.offline_users.lock().unwrap().get(&name).unwrap() + ); + tracing::debug!( + "User offline deref ptr: {:p}", + *state.offline_users.lock().unwrap().get(&name).unwrap() + ); tx.send(server_summary_update(state))?; tx.send(chat_meta_update(state))?; diff --git a/server/src/main.rs b/server/src/main.rs index 8784604..7b8c1a5 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -8,6 +8,7 @@ use std::{ fs::{read_to_string, File}, io::{BufRead, BufReader}, net::SocketAddr, + pin::Pin, sync::{Arc, Mutex}, }; use tokio::sync::broadcast; @@ -43,7 +44,8 @@ fn load_names(path: &str) -> Result> { // Our shared state pub struct AppState { // We require unique usernames. This tracks which usernames have been taken. - users: Mutex>, + online_users: Mutex>>>, + offline_users: Mutex>>>, // Channel used to send messages to all connected clients. tx: broadcast::Sender, // Master card decks @@ -67,14 +69,16 @@ async fn main() -> Result<()> { // Set up application state for use with with_state(). let (tx, _rx) = broadcast::channel(100); - let users = Mutex::new(HashMap::::new()); + let online_users = Mutex::new(HashMap::>>::new()); + let offline_users = Mutex::new(HashMap::>>::new()); let all_cards = load_cards_from_json("data/cah-cards-full.json")?; let games = Mutex::new(vec![]); let first_names = load_names("data/first.txt")?; let last_names = load_names("data/last.txt")?; let app_state = Arc::new(AppState { - users, + online_users, + offline_users, tx, all_cards, games,