idk i'm tired
This commit is contained in:
parent
1e5ef3b801
commit
6bad0e36b2
4 changed files with 143 additions and 155 deletions
|
@ -29,6 +29,7 @@ pub enum GameHandlerMessage {
|
|||
|
||||
/// Handles game stuff
|
||||
pub struct GameHandler {
|
||||
/// Global state pointer
|
||||
state: Arc<AppState>,
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue