cards/server/src/message_handler.rs

165 lines
5.5 KiB
Rust
Raw Normal View History

use crate::user_handler::*;
use crate::AppState;
2024-08-17 21:55:15 -04:00
use crate::GameHandlerMessage::*;
use crate::UserHandlerMessage::*;
2024-08-08 04:54:02 -04:00
use axum::extract::ws::{CloseFrame, Message};
use lib::*;
use serde_json::{from_str, to_string};
use std::net::SocketAddr;
use std::sync::Arc;
2024-08-15 01:56:11 -04:00
/// Handles incoming messages
pub struct MessageHandler {
2024-08-15 01:56:11 -04:00
/// Global state pointer
state: Arc<AppState>,
}
impl MessageHandler {
2024-08-15 01:56:11 -04:00
/// Returns new MessageHandler object
pub fn new(state: Arc<AppState>) -> Self {
MessageHandler { state }
}
2024-08-15 01:56:11 -04:00
/// Handles incoming messages
pub async fn handle(&self, addr: SocketAddr, message: Message) {
match message {
Message::Text(text) => match text {
_chat_message if let Ok(chat_message) = from_str::<ChatMessage>(&text) => {
2024-08-12 17:14:27 -04:00
// TODO: This should be delegated to user handler and an outgoing message and/or chat handler
let msg = format! {"{0}: {1}", self.state.online_users.read().unwrap().get(&addr).unwrap().read().unwrap().name, chat_message.text};
tracing::debug!("{msg}");
self.state
.broadcast_tx
.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap())
.unwrap();
}
2024-08-15 01:56:11 -04:00
_user_log_in_request
if let Ok(user_log_in) = from_str::<UserLogInRequest>(&text) =>
{
self.state
.users_tx
2024-08-17 21:55:15 -04:00
.send(UserLogIn {
username: user_log_in.username,
addr,
})
.await
.unwrap();
tracing::debug!("passed login to user handler");
}
2024-08-15 01:56:11 -04:00
_new_game_request if let Ok(new_game) = from_str::<NewGameRequest>(&text) => {
2024-08-09 01:21:04 -04:00
self.state
.games_tx
2024-08-17 21:55:15 -04:00
.send(NewGame { addr, new_game })
2024-08-09 01:21:04 -04:00
.await
.unwrap();
2024-08-08 05:29:32 -04:00
}
2024-08-14 00:16:54 -04:00
_join_game_request if let Ok(join_request) = from_str::<GameJoinRequest>(&text) => {
self.state
.games_tx
2024-08-17 21:55:15 -04:00
.send(JoinGame {
2024-08-15 01:56:11 -04:00
addr,
id: join_request.id,
})
2024-08-14 00:16:54 -04:00
.await
.unwrap();
}
2024-08-17 21:55:15 -04:00
_player_move_request
if let Ok(move_request) = from_str::<PlayerMoveRequest>(&text) =>
{
2024-08-18 18:48:37 -04:00
if move_request.card_ids.is_empty() {
tracing::error!("Move request card_ids is empty! Ignoring...");
2024-08-17 21:55:15 -04:00
return;
}
if move_request.game_id == "".to_string() {
tracing::error!("Move request game_id is empty! Ignoring...");
return;
} else {
self.state
.games_tx
2024-08-18 18:48:37 -04:00
.send(MoveRequest(move_request, addr))
2024-08-17 21:55:15 -04:00
.await
.unwrap();
}
}
_ => tracing::debug!("Unhandled text from {}", addr),
},
2024-08-15 01:56:11 -04:00
Message::Binary(data) => tracing::debug!("{} sent binary: {:?}", addr, data),
2024-08-15 01:56:11 -04:00
2024-08-08 04:54:02 -04:00
Message::Close(close_frame) => {
self.handle_close(close_frame, addr);
}
2024-08-15 01:56:11 -04:00
Message::Ping(ping) => {
tracing::debug!("Pong received with: {:?}", ping);
}
2024-08-15 01:56:11 -04:00
Message::Pong(pong) => {
tracing::debug!("Pong received with: {:?}", pong);
}
}
}
2024-08-08 04:54:02 -04:00
/// This runs when a connection closes
fn handle_close(&self, close_frame: Option<CloseFrame>, addr: SocketAddr) {
2024-08-15 01:56:11 -04:00
let user_name = self
2024-08-08 04:54:02 -04:00
.state
.online_users
.read()
.unwrap()
.get(&addr)
.unwrap()
.read()
.unwrap()
.name
.clone();
2024-08-15 01:56:11 -04:00
// Send client updates
2024-08-08 04:54:02 -04:00
self.state
.broadcast_tx
.send(meta_server_summary_update(&self.state))
.unwrap();
self.state
.broadcast_tx
.send(meta_chat_update(&self.state))
.unwrap();
2024-08-15 01:56:11 -04:00
// Announce User left in chat
let msg = ChatMessage {
text: format!("{0} left.", &user_name),
};
tracing::debug!("{}", msg.text);
self.state
.broadcast_tx
.send(to_string::<ChatMessage>(&msg).unwrap())
.unwrap();
// Process close frame
if let Some(cf) = close_frame {
tracing::debug!(
"Close received from {0} with code: {1} and reason: {2}",
&user_name,
cf.code,
cf.reason
)
} else {
tracing::debug!("close received without close frame")
}
// Move user to offline
// This should probably happen first/immediately but moving down here avoids a clone
self.state.offline_users.write().unwrap().insert(
user_name,
self.state
.online_users
.write()
.unwrap()
.remove(&addr)
.unwrap(),
);
2024-08-08 04:54:02 -04:00
}
}