Compare commits

...

2 commits

5 changed files with 157 additions and 108 deletions

4
Cargo.lock generated
View file

@ -133,9 +133,9 @@ dependencies = [
[[package]] [[package]]
name = "async-compression" name = "async-compression"
version = "0.4.13" version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e614738943d3f68c628ae3dbce7c3daffb196665f82f8c8ea6b65de73c79429" checksum = "998282f8f49ccd6116b0ed8a4de0fbd3151697920e7c7533416d6e25e76434a7"
dependencies = [ dependencies = [
"brotli", "brotli",
"flate2", "flate2",

View file

@ -9,6 +9,9 @@ use std::{
}; };
use uuid::Uuid; use uuid::Uuid;
// Game logic
// NOTE: Don't try to send messages from here, that's the job of the associated handler
/// Internal manifest for making a new game /// Internal manifest for making a new game
#[derive(Debug)] #[derive(Debug)]
pub struct NewGameManifest { pub struct NewGameManifest {

View file

@ -119,10 +119,14 @@ impl GameHandler {
tx.send(DmUser(SendChatMessage(message), Addr(addr))).await tx.send(DmUser(SendChatMessage(message), Addr(addr))).await
{ {
tracing::error!("Could not send message: {}", e); tracing::error!("Could not send message: {}", e);
}; }
}) })
} }
Ok(None) => tokio::spawn(async move { tracing::debug!("TODO") }), Ok(None) => {
tokio::spawn(
async move { tracing::debug!("TODO: whatever i'm supposed to do") },
)
}
Ok(Some((judge_round, czar_id))) => { Ok(Some((judge_round, czar_id))) => {
let tx = self.state.users_tx.clone(); let tx = self.state.users_tx.clone();
@ -132,7 +136,7 @@ impl GameHandler {
.await .await
{ {
tracing::error!("Could not send message: {}", e); tracing::error!("Could not send message: {}", e);
}; }
}) })
} }
}; };
@ -392,22 +396,22 @@ impl GameHandler {
self.send_game_meta_update(vec![game_id]); self.send_game_meta_update(vec![game_id]);
// Broadcast game browser update // Broadcast game browser update
if let Err(e) = self let msg = meta_games_browser_update(&self.state);
.state let tx = self.state.broadcast_tx.clone();
.broadcast_tx tokio::spawn(async move {
.send(meta_games_browser_update(&self.state)) if let Err(e) = tx.send(msg) {
{
tracing::error!("Could not broadcast game browser update: {}", e); tracing::error!("Could not broadcast game browser update: {}", e);
}; }
});
// Broadcast server meta update // Broadcast server meta update
if let Err(e) = self let msg = meta_server_summary_update(&self.state);
.state let tx = self.state.broadcast_tx.clone();
.broadcast_tx tokio::spawn(async move {
.send(meta_server_summary_update(&self.state)) if let Err(e) = tx.send(msg) {
{
tracing::error!("Could not broadcast server meta update: {}", e); tracing::error!("Could not broadcast server meta update: {}", e);
}; }
});
} else { } else {
tracing::error!("Attempted to create game for nonexistent player!"); tracing::error!("Attempted to create game for nonexistent player!");
} }

View file

@ -33,36 +33,45 @@ impl MessageHandler {
msg = format! {"{0}: {1}", self.state.online_users.read().unwrap().get(&addr).unwrap().read().unwrap().name, chat_message.text}; msg = format! {"{0}: {1}", self.state.online_users.read().unwrap().get(&addr).unwrap().read().unwrap().name, chat_message.text};
} }
if let Err(e) = self // Broadcast incoming chat message
.state let broadcast_message =
.broadcast_tx to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap();
.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap()) let tx = self.state.broadcast_tx.clone();
{ tokio::spawn(async move {
if let Err(e) = tx.send(broadcast_message) {
tracing::error!("Error broadcasting Chat message: {}", e) tracing::error!("Error broadcasting Chat message: {}", e)
}; }
});
} }
_user_log_in_request _user_log_in_request
if let Ok(user_log_in) = from_str::<UserLogInRequest>(&text) => if let Ok(user_log_in) = from_str::<UserLogInRequest>(&text) =>
{ {
if let Err(e) = self.state.users_tx.send(UserLogIn(user_log_in, addr)).await { let msg = UserLogIn(user_log_in, addr);
let tx = self.state.users_tx.clone();
tokio::spawn(async move {
if let Err(e) = tx.send(msg).await {
tracing::error!("Error sending user login: {}", e) tracing::error!("Error sending user login: {}", e)
}; }
});
} }
_new_game_request if let Ok(new_game) = from_str::<NewGameRequest>(&text) => { _new_game_request if let Ok(new_game) = from_str::<NewGameRequest>(&text) => {
if let Err(e) = self.state.games_tx.send(NewGame(new_game, addr)).await { let msg = NewGame(new_game, addr);
let tx = self.state.games_tx.clone();
tokio::spawn(async move {
if let Err(e) = tx.send(msg).await {
tracing::error!("Error requesting new game: {}", e) tracing::error!("Error requesting new game: {}", e)
}; }
});
} }
_join_game_request if let Ok(join_request) = from_str::<GameJoinRequest>(&text) => { _join_game_request if let Ok(join_request) = from_str::<GameJoinRequest>(&text) => {
if let Err(e) = self let msg = JoinGame(join_request.id, addr);
.state let tx = self.state.games_tx.clone();
.games_tx tokio::spawn(async move {
.send(JoinGame(join_request.id, addr)) if let Err(e) = tx.send(msg).await {
.await
{
tracing::error!("Error requesting game join: {}", e) tracing::error!("Error requesting game join: {}", e)
}; }
});
} }
_player_move_request _player_move_request
@ -76,14 +85,13 @@ impl MessageHandler {
tracing::error!("Move request game_id is empty! Ignoring..."); tracing::error!("Move request game_id is empty! Ignoring...");
return; return;
} else { } else {
if let Err(e) = self let msg = MoveRequest(move_request, addr);
.state let tx = self.state.games_tx.clone();
.games_tx tokio::spawn(async move {
.send(MoveRequest(move_request, addr)) if let Err(e) = tx.send(msg).await {
.await
{
tracing::error!("Error sending move request: {}", e) tracing::error!("Error sending move request: {}", e)
}; }
});
} }
} }
@ -91,23 +99,26 @@ impl MessageHandler {
if let Ok(judge_request) = from_str::<JudgeDecisionRequest>(&text) => if let Ok(judge_request) = from_str::<JudgeDecisionRequest>(&text) =>
{ {
if !judge_request.winning_cards.is_empty() { if !judge_request.winning_cards.is_empty() {
if let Err(e) = self let msg = JudgeDecision(judge_request, addr);
.state let tx = self.state.games_tx.clone();
.games_tx tokio::spawn(async move {
.send(JudgeDecision(judge_request, addr)) if let Err(e) = tx.send(msg).await {
.await
{
tracing::error!("Error sending Judge Decision: {}", e) tracing::error!("Error sending Judge Decision: {}", e)
}; }
});
} else { } else {
tracing::error!("Judge request received with empty cards"); tracing::error!("Judge request received with empty cards");
} }
} }
_delete_game if let Ok(delete_request) = from_str::<GameDeleteRequest>(&text) => { _delete_game if let Ok(delete_request) = from_str::<GameDeleteRequest>(&text) => {
if let Err(e) = self.state.games_tx.send(DeleteGame(delete_request)).await { let msg = DeleteGame(delete_request);
let tx = self.state.games_tx.clone();
tokio::spawn(async move {
if let Err(e) = tx.send(msg).await {
tracing::error!("Error sending delete game: {}", e) tracing::error!("Error sending delete game: {}", e)
}; }
});
} }
_ => tracing::error!( _ => tracing::error!(
@ -117,7 +128,11 @@ impl MessageHandler {
), ),
}, },
Message::Binary(data) => tracing::error!("{} sent binary: {:?}\n TODO: Probably close connection here", addr, data), Message::Binary(data) => tracing::error!(
"{} sent binary: {:?}\n TODO: Probably close connection here",
addr,
data
),
Message::Close(close_frame) => { Message::Close(close_frame) => {
self.handle_close(close_frame, addr); self.handle_close(close_frame, addr);
@ -135,6 +150,7 @@ impl MessageHandler {
/// This runs when a connection closes /// This runs when a connection closes
fn handle_close(&self, close_frame: Option<CloseFrame>, addr: SocketAddr) { fn handle_close(&self, close_frame: Option<CloseFrame>, addr: SocketAddr) {
// TODO: this is user handler's job
let user_name = self let user_name = self
.state .state
.online_users .online_users
@ -151,13 +167,13 @@ impl MessageHandler {
let msg = ChatMessage { let msg = ChatMessage {
text: format!("{0} left.", &user_name), text: format!("{0} left.", &user_name),
}; };
if let Err(e) = self let chat_message = to_string::<ChatMessage>(&msg).unwrap();
.state let tx = self.state.broadcast_tx.clone();
.broadcast_tx tokio::spawn(async move {
.send(to_string::<ChatMessage>(&msg).unwrap()) if let Err(e) = tx.send(chat_message) {
{
tracing::error!("Error broadcasting user leave message: {}", e) tracing::error!("Error broadcasting user leave message: {}", e)
}; }
});
// Process close frame // Process close frame
if let Some(cf) = close_frame { if let Some(cf) = close_frame {
@ -172,6 +188,7 @@ impl MessageHandler {
} }
// Move user to offline // Move user to offline
// TODO: This is user handler's job
self.state.offline_users.write().unwrap().insert( self.state.offline_users.write().unwrap().insert(
user_name, user_name,
self.state self.state
@ -183,15 +200,19 @@ impl MessageHandler {
); );
// Send client updates // Send client updates
if let Err(e) = self let msg = meta_server_summary_update(&self.state);
.state let tx = self.state.broadcast_tx.clone();
.broadcast_tx tokio::spawn(async move {
.send(meta_server_summary_update(&self.state)) if let Err(e) = tx.send(msg) {
{
tracing::error!("Error broadcasting server summary update: {}", e) tracing::error!("Error broadcasting server summary update: {}", e)
}; }
if let Err(e) = self.state.broadcast_tx.send(meta_chat_update(&self.state)) { });
let msg = meta_chat_update(&self.state);
let tx = self.state.broadcast_tx.clone();
tokio::spawn(async move {
if let Err(e) = tx.send(msg) {
tracing::error!("Error broadcasting chat update: {}", e) tracing::error!("Error broadcasting chat update: {}", e)
}; }
});
} }
} }

View file

@ -8,6 +8,8 @@ use serde_json::to_string;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
// TODO: clean up all this tx/msg mess
/// Handles users /// Handles users
pub struct UserHandler { pub struct UserHandler {
/// Pointer to global state /// Pointer to global state
@ -83,32 +85,40 @@ impl UserHandler {
match message { match message {
SendUserUpdate(message) => { SendUserUpdate(message) => {
let msg = to_string::<UserUpdate>(&message).unwrap(); let msg = to_string::<UserUpdate>(&message).unwrap();
tokio::spawn(async move {
if let Err(e) = tx.send(msg).await { if let Err(e) = tx.send(msg).await {
tracing::error!("Error sending user update: {}", e) tracing::error!("Error sending user update: {}", e)
}; }
});
} }
SendChatMessage(message) => { SendChatMessage(message) => {
let msg = to_string::<ChatMessage>(&message).unwrap(); let msg = to_string::<ChatMessage>(&message).unwrap();
tokio::spawn(async move {
if let Err(e) = tx.send(msg).await { if let Err(e) = tx.send(msg).await {
tracing::error!("Error sending chat message: {}", e) tracing::error!("Error sending chat message: {}", e)
}; }
});
} }
SendJudgeRound(message) => { SendJudgeRound(message) => {
let msg = to_string::<JudgeRound>(&message).unwrap(); let msg = to_string::<JudgeRound>(&message).unwrap();
tokio::spawn(async move {
if let Err(e) = tx.send(msg).await { if let Err(e) = tx.send(msg).await {
tracing::error!("Error sending judge round: {}", e) tracing::error!("Error sending judge round: {}", e)
}; }
});
} }
} }
} }
/// Create, register, and hydrate new user /// Create, register, and hydrate new user
async fn set_up_new_user(&self, user: User, addr: SocketAddr) { async fn set_up_new_user(&self, user: User, addr: SocketAddr) {
let tx = user.tx.clone(); let user_tx = user.tx.clone();
let new_user = Arc::new(RwLock::new(user)); let new_user = Arc::new(RwLock::new(user));
// Notify client of new username // Notify client of new username
let _ = tx.send(user_client_self_update(&new_user)).await; let tx = user_tx.clone();
let msg = user_client_self_update(&new_user);
tokio::spawn(async move { tx.send(msg).await });
// Register uuid // Register uuid
self.state self.state
@ -125,23 +135,29 @@ impl UserHandler {
.insert(addr, new_user.clone()); .insert(addr, new_user.clone());
// Hydrate client // Hydrate client
let _ = tx.send(meta_games_browser_update(&self.state)).await; let tx = user_tx.clone();
let _ = tx.send(meta_new_game_card_packs(&self.state)).await; let msg = meta_games_browser_update(&self.state);
tokio::spawn(async move { tx.send(msg).await });
let tx = user_tx.clone();
let msg = meta_new_game_card_packs(&self.state);
tokio::spawn(async move { tx.send(msg).await });
// Broadcast new user's existence // Broadcast new user's existence
// TODO: this should probably be combined and sent as one // TODO: this should probably be combined and sent as one
let _ = &self let tx = self.state.broadcast_tx.clone();
.state let msg = meta_announce_user_join(&self.state, &addr);
.broadcast_tx tokio::spawn(async move { tx.send(msg) });
.send(meta_announce_user_join(&self.state, &addr));
let _ = &self let tx = self.state.broadcast_tx.clone();
.state let msg = meta_server_summary_update(&self.state);
.broadcast_tx tokio::spawn(async move { tx.send(msg) });
.send(meta_server_summary_update(&self.state)); let tx = self.state.broadcast_tx.clone();
let _ = &self.state.broadcast_tx.send(meta_chat_update(&self.state)); let msg = meta_chat_update(&self.state);
tokio::spawn(async move { tx.send(msg) });
// TODO: this races the broadcasts but if it's done last it'll probably show up last... // TODO: this races the broadcasts but if it's done last it'll probably show up last...
let _ = tx.send(meta_motd()).await; let tx = user_tx.clone();
tokio::spawn(async move { tx.send(meta_motd()).await });
} }
/// Handle user login /// Handle user login
@ -199,7 +215,9 @@ impl UserHandler {
old_name, old_name,
new_name new_name
}; };
let _ = broadcast_tx.send(to_string(&ChatMessage { text: msg }).unwrap()); let tx = broadcast_tx.clone();
let msg = to_string(&ChatMessage { text: msg }).unwrap();
tokio::spawn(async move { tx.send(msg) });
} }
// Check if name is taken by an online user // Check if name is taken by an online user
else if self else if self
@ -245,8 +263,9 @@ impl UserHandler {
old_name, old_name,
new_name new_name
}; };
let _ = let chat_message = to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap();
broadcast_tx.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap()); let tx = broadcast_tx.clone();
tokio::spawn(async move { tx.send(chat_message) });
} }
// Send the user their new name // Send the user their new name
@ -279,15 +298,17 @@ impl UserHandler {
); );
let tx = self.state.games_tx.clone(); let tx = self.state.games_tx.clone();
tokio::spawn(async move { tokio::spawn(async move { tx.send(msg).await });
let _ = tx.send(msg).await;
});
} }
} }
} }
// Send client updates // Send client updates
let _ = broadcast_tx.send(meta_games_browser_update(&self.state)); let tx = broadcast_tx.clone();
let _ = broadcast_tx.send(meta_chat_update(&self.state)); let msg = meta_games_browser_update(&self.state);
tokio::spawn(async move { tx.send(msg) });
let tx = broadcast_tx.clone();
let msg = meta_chat_update(&self.state);
tokio::spawn(async move { tx.send(msg) });
} }
} }