idk i'm tired

This commit is contained in:
Adam 2024-08-15 01:56:11 -04:00
parent 1e5ef3b801
commit 6bad0e36b2
4 changed files with 143 additions and 155 deletions

View file

@ -29,6 +29,7 @@ pub enum GameHandlerMessage {
/// Handles game stuff
pub struct GameHandler {
/// Global state pointer
state: Arc<AppState>,
}

View file

@ -3,7 +3,7 @@
use crate::game_handler::*;
use anyhow::{Context, Result};
use axum::extract::ws::Message;
use game_handler::GameHandlerMessage;
use game_handler::*;
use lib::*;
use std::{
collections::{HashMap, HashSet},
@ -14,7 +14,7 @@ use std::{
};
use tokio::sync::mpsc::Sender;
use tokio::sync::{broadcast, mpsc};
use user_handler::UserHandlerMessage;
use user_handler::*;
use uuid::Uuid;
pub mod game_handler;
pub mod message_handler;

View file

@ -7,15 +7,19 @@ use serde_json::{from_str, to_string};
use std::net::SocketAddr;
use std::sync::Arc;
/// Handles incoming messages
pub struct MessageHandler {
/// Global state pointer
state: Arc<AppState>,
}
impl MessageHandler {
/// Returns new MessageHandler object
pub fn new(state: Arc<AppState>) -> Self {
MessageHandler { state }
}
/// Handles incoming messages
pub async fn handle(&self, addr: SocketAddr, message: Message) {
match message {
Message::Text(text) => match text {
@ -28,7 +32,9 @@ impl MessageHandler {
.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap())
.unwrap();
}
_user_log_in if let Ok(user_log_in) = from_str::<UserLogInRequest>(&text) => {
_user_log_in_request
if let Ok(user_log_in) = from_str::<UserLogInRequest>(&text) =>
{
self.state
.users_tx
.send(UserHandlerMessage::UserLogIn {
@ -39,7 +45,7 @@ impl MessageHandler {
.unwrap();
tracing::debug!("passed login to user handler");
}
_new_game if let Ok(new_game) = from_str::<NewGameRequest>(&text) => {
_new_game_request if let Ok(new_game) = from_str::<NewGameRequest>(&text) => {
self.state
.games_tx
.send(GameHandlerMessage::NewGame { addr, new_game })
@ -50,21 +56,28 @@ impl MessageHandler {
_join_game_request if let Ok(join_request) = from_str::<GameJoinRequest>(&text) => {
self.state
.games_tx
.send(GameHandlerMessage::JoinGame { addr, id: join_request.id })
.send(GameHandlerMessage::JoinGame {
addr,
id: join_request.id,
})
.await
.unwrap();
}
_ => tracing::debug!("Unhandled text from {}", addr),
},
Message::Binary(data) => tracing::debug!("{} sent binary: {:?}", addr, data),
Message::Close(close_frame) => {
self.handle_close(close_frame, addr);
}
Message::Pong(ping) => {
Message::Ping(ping) => {
tracing::debug!("Pong received with: {:?}", ping);
}
Message::Ping(pong) => {
Message::Pong(pong) => {
tracing::debug!("Pong received with: {:?}", pong);
}
}
@ -72,48 +85,7 @@ impl MessageHandler {
/// This runs when a connection closes
fn handle_close(&self, close_frame: Option<CloseFrame>, addr: SocketAddr) {
if let Some(cf) = close_frame {
tracing::debug!(
"Close received from {0} with code: {1} and reason: {2}",
self.state
.online_users
.read()
.unwrap()
.get(&addr)
.unwrap()
.read()
.unwrap()
.name,
cf.code,
cf.reason
)
} else {
tracing::debug!("close received without close frame")
}
let msg = ChatMessage {
text: format!(
"{0} left.",
self.state
.online_users
.read()
.unwrap()
.get(&addr)
.unwrap()
.read()
.unwrap()
.name
),
};
tracing::debug!("{}", msg.text);
self.state
.broadcast_tx
.send(to_string::<ChatMessage>(&msg).unwrap())
.unwrap();
// Move user to offline
let name = self
let user_name = self
.state
.online_users
.read()
@ -125,16 +97,7 @@ impl MessageHandler {
.name
.clone();
self.state.offline_users.write().unwrap().insert(
name.clone(),
self.state
.online_users
.write()
.unwrap()
.remove(&addr)
.unwrap(),
);
// Send client updates
self.state
.broadcast_tx
.send(meta_server_summary_update(&self.state))
@ -143,5 +106,39 @@ impl MessageHandler {
.broadcast_tx
.send(meta_chat_update(&self.state))
.unwrap();
// 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(),
);
}
}

View file

@ -1,4 +1,5 @@
use crate::AppState;
use crate::SendUserMessage::*;
use crate::User;
use crate::UserHandlerMessage::*;
use lib::*;
@ -6,21 +7,41 @@ use serde_json::to_string;
use std::net::SocketAddr;
use std::sync::{Arc, RwLock};
pub enum UserHandlerMessage {
NewUser { user: User, addr: SocketAddr },
UserLogIn { username: String, addr: SocketAddr },
DmUserAddr { addr: SocketAddr, message: String },
}
/// Handles users
pub struct UserHandler {
/// Pointer to global state
state: Arc<AppState>,
}
/// For interacting with the user handler
pub enum UserHandlerMessage {
NewUser {
user: User,
addr: SocketAddr,
},
UserLogIn {
username: String,
addr: SocketAddr,
},
DmUserAddr {
addr: SocketAddr,
message: SendUserMessage,
},
}
/// Types of messages that can be sent to a user as a DM
pub enum SendUserMessage {
SendUserUpdate(UserUpdate),
SendChatMessage(ChatMessage),
}
impl UserHandler {
/// Returns new UserHandler
pub fn new(state: Arc<AppState>) -> Self {
UserHandler { state }
}
/// Handles incoming messages
pub async fn handle(&self, message: UserHandlerMessage) {
match message {
NewUser { user, addr } => {
@ -32,8 +53,8 @@ impl UserHandler {
}
}
async fn send_message_addr(&self, addr: SocketAddr, message: String) {
let msg = to_string::<ChatMessage>(&ChatMessage { text: message }).unwrap();
/// Send message direct to a single user via addr
async fn send_message_addr(&self, addr: SocketAddr, message: SendUserMessage) {
let tx = self
.state
.online_users
@ -45,14 +66,20 @@ impl UserHandler {
.unwrap()
.tx
.clone();
match message {
SendUserUpdate(message) => {
let msg = to_string::<UserUpdate>(&message).unwrap();
tx.send(msg).await.unwrap()
}
SendChatMessage(message) => {
let msg = to_string::<ChatMessage>(&message).unwrap();
tx.send(msg).await.unwrap()
}
}
}
/// Create, register, and hydrate new user
async fn set_up_new_user(&self, user: User, addr: SocketAddr) {
//
// Create, Register, and Hydrate new user
//
let tx = user.tx.clone();
let new_user = Arc::new(RwLock::new(user));
@ -77,7 +104,6 @@ impl UserHandler {
tx.send(meta_games_browser_update(&self.state))
.await
.unwrap();
tx.send(meta_new_game_card_packs(&self.state))
.await
.unwrap();
@ -87,39 +113,21 @@ impl UserHandler {
let _ = &self
.state
.broadcast_tx
.send(meta_announce_user_join(&self.state, &addr))
.unwrap();
.send(meta_announce_user_join(&self.state, &addr));
let _ = &self
.state
.broadcast_tx
.send(meta_server_summary_update(&self.state))
.unwrap();
let _ = &self
.state
.broadcast_tx
.send(meta_chat_update(&self.state))
.unwrap();
.send(meta_server_summary_update(&self.state));
let _ = &self.state.broadcast_tx.send(meta_chat_update(&self.state));
// 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...
tx.send(meta_motd()).await.unwrap();
}
/// Handle user login
async fn login(&self, username: String, addr: SocketAddr) {
// User's DM channel
let dm = self
.state
.online_users
.read()
.unwrap()
.get(&addr)
.unwrap()
.read()
.unwrap()
.tx
.clone();
let broadcast = self.state.broadcast_tx.clone();
let broadcast_tx = self.state.broadcast_tx.clone();
let new_name = username.clone();
let old_name = self
.state
.online_users
@ -132,8 +140,7 @@ impl UserHandler {
.name
.clone();
let new_name = username.clone();
// Resume user's old session if they exist as offline
if self
.state
.offline_users
@ -156,47 +163,47 @@ impl UserHandler {
)
.unwrap();
// Send welcome back messages
let msg = format! {
"{0} changed name to {1}. Welcome back!",
old_name,
new_name
};
dm.send(
serde_json::to_string(&ChatMessage {
text: "Welcome back!".to_string(),
})
.unwrap(),
)
.await
.unwrap();
tracing::debug!("{msg}");
} else if self
tracing::debug!("{}", &msg);
let _ = broadcast_tx.send(to_string(&ChatMessage { text: msg }).unwrap());
}
// Check if name is taken by an online user
else if self
.state
.reserved_names
.read()
.unwrap()
.contains(&new_name)
{
tracing::debug!("name is taken");
dm.send(
serde_json::to_string(&ChatMessage {
self.send_message_addr(
addr,
SendChatMessage(ChatMessage {
text: "Name is taken".to_string(),
})
.unwrap(),
}),
)
.await
.unwrap();
.await;
tracing::debug!("{}", old_name.clone());
dm.send(
to_string::<UserUpdate>(&UserUpdate {
self.send_message_addr(
addr,
SendUserUpdate(UserUpdate {
username: old_name.clone(),
})
.unwrap(),
}),
)
.await
.unwrap();
.await;
} else {
// Reserve name
self.state
.reserved_names
.write()
.unwrap()
.insert(new_name.clone());
// Change user's name
self.state
.online_users
.write()
@ -207,48 +214,31 @@ impl UserHandler {
.unwrap()
.change_name(username);
// send the user their new name
self.send_message_addr(
addr,
SendUserUpdate(UserUpdate {
username: new_name.clone(),
}),
)
.await;
// Send chat updates
let msg = format! {
"{0} changed name to {1}.",
old_name,
new_name
};
// Reserve name
self.state
.reserved_names
.write()
.unwrap()
.insert(new_name.clone());
tracing::debug!("{msg}");
broadcast
broadcast_tx
.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap())
.unwrap();
tracing::debug!("Name {} reserved.", &new_name);
// send the user their new name
dm.send(
to_string::<UserUpdate>(&UserUpdate {
username: new_name.clone(),
})
.unwrap(),
)
.await
.unwrap();
}
tracing::debug!(
"Online Users: {} Offline Users: {}",
self.state.online_users.read().unwrap().len(),
self.state.offline_users.read().unwrap().len()
);
broadcast
// Send client updates
broadcast_tx
.send(meta_games_browser_update(&self.state))
.unwrap();
broadcast.send(meta_chat_update(&self.state)).unwrap();
tracing::debug!(" HI! login received {} {} {}", addr, new_name, old_name)
broadcast_tx.send(meta_chat_update(&self.state)).unwrap();
}
}