add submission and judging
This commit is contained in:
parent
9418451af1
commit
5d1ca4a96d
8 changed files with 314 additions and 54 deletions
|
@ -3,12 +3,13 @@ use crate::components::websocket::WebSocketContext;
|
|||
use leptos::*;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[component]
|
||||
pub fn Game() -> impl IntoView {
|
||||
let websocket = expect_context::<WebSocketContext>();
|
||||
let game_meta = expect_context::<ReadSignal<Option<GameStateMeta>>>();
|
||||
let judge_round = expect_context::<ReadSignal<Option<JudgeRound>>>();
|
||||
|
||||
let (game_id, set_game_id) = create_signal("".to_string());
|
||||
let (game_name, set_game_name) = create_signal("".to_string());
|
||||
|
@ -16,14 +17,47 @@ pub fn Game() -> impl IntoView {
|
|||
let (game_players, set_game_players) = create_signal(vec![]);
|
||||
let (game_czar, set_game_czar) = create_signal("".to_string());
|
||||
let (game_black, set_game_black) = create_signal(("".to_string(), 0u8));
|
||||
let (game_white, set_game_white) = create_signal(vec![]);
|
||||
let (player_white, set_player_white) =
|
||||
create_signal::<HashMap<String, WhiteCardMeta>>(HashMap::new());
|
||||
let (_game_white, set_game_white) = create_signal(vec![]);
|
||||
let (selected_cards_ordered, set_selected_cards_ordered) = create_signal::<Vec<String>>(vec![]);
|
||||
let (player_hand, set_player_hand) = create_signal::<Vec<String>>(vec![]);
|
||||
let (player_white, set_player_white) =
|
||||
create_signal::<HashMap<String, WhiteCardMeta>>(HashMap::new());
|
||||
let (card_clicked, set_card_clicked) = create_signal::<String>(String::new());
|
||||
provide_context::<WriteSignal<String>>(set_card_clicked);
|
||||
|
||||
// Handle incoming judge message
|
||||
create_effect(move |_| {
|
||||
judge_round.with(move |judge_round| {
|
||||
set_player_hand.update(|list| {
|
||||
list.clear();
|
||||
});
|
||||
set_player_white.update(|list| {
|
||||
list.clear();
|
||||
});
|
||||
set_card_clicked.update(|list| {
|
||||
list.clear();
|
||||
});
|
||||
set_selected_cards_ordered.update(|list| {
|
||||
list.clear();
|
||||
});
|
||||
|
||||
// Load hand
|
||||
if let Some(judge) = judge_round {
|
||||
for cards in judge.cards_to_judge.clone() {
|
||||
for card in cards {
|
||||
set_player_white.update(|hand| {
|
||||
hand.insert(card.uuid.clone(), card.clone());
|
||||
});
|
||||
set_player_hand.update(|hand| {
|
||||
hand.push(card.uuid.clone());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Handle incoming state update
|
||||
create_effect(move |_| {
|
||||
if let Some(game) = game_meta() {
|
||||
// Clear in case of (re-)joining game
|
||||
|
@ -61,7 +95,7 @@ pub fn Game() -> impl IntoView {
|
|||
}
|
||||
});
|
||||
|
||||
// Move cards back and forth from hand to selected when clicked
|
||||
// Move cards back and forth between hand and selected when clicked
|
||||
create_effect(move |_| {
|
||||
if let Some(card_index) = player_hand()
|
||||
.iter()
|
||||
|
@ -88,16 +122,34 @@ pub fn Game() -> impl IntoView {
|
|||
}
|
||||
});
|
||||
|
||||
// create_effect(move |_| {
|
||||
// logging::log!("{:#?}", selected_cards());
|
||||
// websocket.send(
|
||||
// &to_string(&PlayerMoveRequest {
|
||||
// game_id: game_id(),
|
||||
// card_ids: selected_cards(),
|
||||
// })
|
||||
// .unwrap(),
|
||||
// )
|
||||
// });
|
||||
let submit_cards = move |_| {
|
||||
let tx = websocket.clone();
|
||||
judge_round.with(move |judge| {
|
||||
let mut _message: Option<String> = None;
|
||||
|
||||
if judge.is_some() {
|
||||
_message = Some(
|
||||
to_string(&JudgeDecisionRequest {
|
||||
game_id: game_id(),
|
||||
winning_cards: selected_cards_ordered(),
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
} else {
|
||||
_message = Some(
|
||||
to_string(&PlayerMoveRequest {
|
||||
game_id: game_id(),
|
||||
card_ids: selected_cards_ordered(),
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(msg) = _message {
|
||||
tx.send(&msg);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
view! {
|
||||
<div class="p-1">
|
||||
|
@ -136,6 +188,11 @@ pub fn Game() -> impl IntoView {
|
|||
}
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full inline-flex flex-wrap justify-center">
|
||||
<button type="button" on:click=submit_cards>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
// Player cards
|
||||
<div class="inline-flex flex-wrap justify-center">
|
||||
|
|
|
@ -54,26 +54,29 @@ pub fn Websocket() -> impl IntoView {
|
|||
Rc::new(close.clone()),
|
||||
));
|
||||
|
||||
// TODO: This context stuff can probably be done better
|
||||
|
||||
// Contexts for message handler
|
||||
let (state_summary, set_state_summary) =
|
||||
create_signal::<Option<ServerStateSummary>>(Option::None);
|
||||
let (active_games, set_active_games) = create_signal::<Vec<GameBrowserMeta>>(vec![]);
|
||||
let (user_update, set_user_update) = create_signal::<Option<UserUpdate>>(Option::None);
|
||||
let (chat_update, set_chat_update) = create_signal::<Option<ChatUpdate>>(Option::None);
|
||||
let (judge_round, set_judge_round) = create_signal::<Option<JudgeRound>>(Option::None);
|
||||
let (chat_message, set_chat_message) = create_signal::<Option<ChatMessage>>(Option::None);
|
||||
let (active_games, set_active_games) = create_signal::<Vec<GameBrowserMeta>>(vec![]);
|
||||
let (current_game, set_current_game) = create_signal::<Option<GameStateMeta>>(Option::None);
|
||||
let (card_packs_meta, set_card_packs_meta) = create_signal::<CardPacksMeta>(CardPacksMeta {
|
||||
official_meta: vec![],
|
||||
unofficial_meta: vec![],
|
||||
});
|
||||
|
||||
// provide_context::<ReadSignal<Option<Game>>>(game_object);
|
||||
provide_context::<ReadSignal<CardPacksMeta>>(card_packs_meta);
|
||||
provide_context::<ReadSignal<Option<UserUpdate>>>(user_update);
|
||||
provide_context::<ReadSignal<Option<ChatUpdate>>>(chat_update);
|
||||
provide_context::<ReadSignal<Option<JudgeRound>>>(judge_round);
|
||||
provide_context::<ReadSignal<Option<ChatMessage>>>(chat_message);
|
||||
provide_context::<ReadSignal<Vec<GameBrowserMeta>>>(active_games);
|
||||
provide_context::<ReadSignal<Option<GameStateMeta>>>(current_game);
|
||||
provide_context::<ReadSignal<CardPacksMeta>>(card_packs_meta);
|
||||
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
|
||||
|
||||
// Message handler
|
||||
|
@ -94,6 +97,8 @@ pub fn Websocket() -> impl IntoView {
|
|||
set_current_game(Some(game_update));
|
||||
} else if let Ok(packs_meta_update) = from_str::<CardPacksMeta>(message) {
|
||||
set_card_packs_meta(packs_meta_update);
|
||||
} else if let Ok(judge_update) = from_str::<JudgeRound>(message) {
|
||||
set_judge_round(Some(judge_update));
|
||||
} else {
|
||||
logging::log!("Unhandled message: {}", message);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Judge decision
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct JudgeDecisionRequest {
|
||||
pub game_id: String,
|
||||
pub winning_cards: Vec<String>,
|
||||
}
|
||||
|
||||
/// Judge round
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct JudgeRound {
|
||||
pub cards_to_judge: Vec<Vec<WhiteCardMeta>>,
|
||||
}
|
||||
|
||||
/// Delete game request
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GameDeleteRequest {
|
||||
|
@ -18,7 +29,7 @@ pub struct GameJoinRequest {
|
|||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct PlayerMoveRequest {
|
||||
pub game_id: String,
|
||||
pub card_ids: BTreeSet<String>,
|
||||
pub card_ids: Vec<String>,
|
||||
}
|
||||
|
||||
/// White Card Meta
|
||||
|
|
|
@ -28,6 +28,7 @@ pub enum GameHandlerMessage {
|
|||
id: String,
|
||||
},
|
||||
MoveRequest(PlayerMoveRequest, SocketAddr),
|
||||
JudgeDecision(JudgeDecisionRequest, SocketAddr),
|
||||
}
|
||||
|
||||
/// Handles game stuff
|
||||
|
@ -48,12 +49,14 @@ impl GameHandler {
|
|||
NewGame { addr, new_game } => self.create_new_game(addr, new_game).await,
|
||||
JoinGame { addr, id } => self.join_game(addr, id).await,
|
||||
MoveRequest(request, addr) => self.handle_player_move(request, addr).await,
|
||||
JudgeDecision(request, addr) => self.handle_judging(request, addr).await,
|
||||
}
|
||||
}
|
||||
|
||||
/// Process player move request
|
||||
async fn handle_player_move(&self, request: PlayerMoveRequest, addr: SocketAddr) {
|
||||
let this_player_id = self
|
||||
/// Process judging
|
||||
async fn handle_judging(&self, request: JudgeDecisionRequest, addr: SocketAddr) {
|
||||
// Get pointers
|
||||
let this_user_id = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
|
@ -74,6 +77,8 @@ impl GameHandler {
|
|||
.unwrap()
|
||||
.clone();
|
||||
|
||||
// Check if this player is czar
|
||||
// Check if player is currently Czar
|
||||
if this_game
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -82,19 +87,129 @@ impl GameHandler {
|
|||
.unwrap()
|
||||
.uuid
|
||||
.to_string()
|
||||
== this_player_id
|
||||
== this_user_id
|
||||
{
|
||||
tracing::error!("No! User id is same as current czar");
|
||||
} else {
|
||||
tracing::error!("Ok, but i have nothing to do");
|
||||
// Find user who submitted the card
|
||||
let winning_user_id = this_game
|
||||
.read()
|
||||
.unwrap()
|
||||
.judge_pool
|
||||
.get(&request.winning_cards)
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
tracing::debug!("{:#?} Won the round!", winning_user_id);
|
||||
}
|
||||
}
|
||||
|
||||
tracing::debug!(
|
||||
"Player move received:\nCards: {:#?}\nGame: {}\nPlayer: {}",
|
||||
request.card_ids,
|
||||
request.game_id,
|
||||
this_player_id,
|
||||
);
|
||||
/// Process player move request
|
||||
async fn handle_player_move(&self, request: PlayerMoveRequest, addr: SocketAddr) {
|
||||
// Get pointers
|
||||
let this_user_id = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.uuid
|
||||
.to_string();
|
||||
|
||||
let this_game = self
|
||||
.state
|
||||
.games
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&request.game_id)
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
// Do the stuff
|
||||
|
||||
// Check if player is currently Czar
|
||||
if this_game
|
||||
.read()
|
||||
.unwrap()
|
||||
.czar
|
||||
.read()
|
||||
.unwrap()
|
||||
.uuid
|
||||
.to_string()
|
||||
== this_user_id
|
||||
{
|
||||
// Tell player no
|
||||
let _ = self
|
||||
.state
|
||||
.users_tx
|
||||
.send(DmUserAddr {
|
||||
addr,
|
||||
message: SendChatMessage(ChatMessage {
|
||||
text: "You can't submit cards to judge, you ARE the judge!".to_string(),
|
||||
}),
|
||||
})
|
||||
.await;
|
||||
} else {
|
||||
// Ignore extra cards
|
||||
let current_round_pick: usize = this_game.read().unwrap().current_black.pick.into();
|
||||
// TODO: handle not enough cards submitted
|
||||
let trimmed = &request.card_ids[..current_round_pick];
|
||||
|
||||
// Put cards into game judge pool
|
||||
this_game
|
||||
.write()
|
||||
.unwrap()
|
||||
.judge_pool
|
||||
.insert(trimmed.to_vec(), this_user_id.clone());
|
||||
|
||||
// Check if this is the last player to submit
|
||||
if this_game.read().unwrap().judge_pool.len()
|
||||
== this_game.read().unwrap().players.len() - 1
|
||||
{
|
||||
let message = SendJudgeRound(JudgeRound {
|
||||
cards_to_judge: this_game
|
||||
.read()
|
||||
.unwrap()
|
||||
.judge_pool
|
||||
.keys()
|
||||
.into_iter()
|
||||
.map(|group| {
|
||||
group
|
||||
.iter()
|
||||
.map(|id| WhiteCardMeta {
|
||||
uuid: self
|
||||
.state
|
||||
.white_cards_by_id
|
||||
.get(id)
|
||||
.unwrap()
|
||||
.uuid
|
||||
.to_string(),
|
||||
text: self
|
||||
.state
|
||||
.white_cards_by_id
|
||||
.get(id)
|
||||
.unwrap()
|
||||
.text
|
||||
.clone(),
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
|
||||
tracing::debug!("send for judging");
|
||||
let czar_id = this_game.read().unwrap().czar.read().unwrap().uuid.clone();
|
||||
let _ = self
|
||||
.state
|
||||
.users_tx
|
||||
.send(DmUserId {
|
||||
id: czar_id,
|
||||
message,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Puts a user in a game
|
||||
|
@ -304,11 +419,11 @@ struct CardBlackFromJSON {
|
|||
|
||||
/// A processed white card for use server-side
|
||||
#[derive(Debug)]
|
||||
struct CardWhiteWithID {
|
||||
pub struct CardWhiteWithID {
|
||||
/// Unique identifier
|
||||
uuid: Uuid,
|
||||
pub uuid: Uuid,
|
||||
/// Card text
|
||||
text: String,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// A processed black card for use server-side
|
||||
|
@ -366,16 +481,19 @@ pub struct Game {
|
|||
pub name: String,
|
||||
/// The host user of the game
|
||||
pub host: Arc<RwLock<User>>,
|
||||
/// White draw pile
|
||||
white: Vec<Arc<CardWhiteWithID>>,
|
||||
/// Current card czar
|
||||
pub czar: Arc<RwLock<User>>,
|
||||
/// Packs selected for this game
|
||||
pub packs: Vec<u8>,
|
||||
/// White draw pile
|
||||
white: Vec<Arc<CardWhiteWithID>>,
|
||||
/// Black draw pile
|
||||
black: Vec<Arc<CardBlackWithID>>,
|
||||
pub players: HashMap<Uuid, Player>,
|
||||
pub players: HashMap<String, Player>,
|
||||
/// Black card for the current round
|
||||
current_black: Arc<CardBlackWithID>,
|
||||
pub packs: Vec<u8>,
|
||||
/// Judge pool
|
||||
judge_pool: HashMap<Vec<String>, String>,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
|
@ -424,6 +542,7 @@ impl Game {
|
|||
players: HashMap::new(),
|
||||
current_black,
|
||||
packs: request.packs.clone(),
|
||||
judge_pool: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,7 +582,13 @@ impl Game {
|
|||
}
|
||||
|
||||
/// Parse json for card data
|
||||
pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
|
||||
pub fn load_cards_from_json(
|
||||
path: &str,
|
||||
) -> Result<(
|
||||
CardPacks,
|
||||
CardPacksMeta,
|
||||
HashMap<String, Arc<CardWhiteWithID>>,
|
||||
)> {
|
||||
// Load in json
|
||||
let data: String =
|
||||
read_to_string(path).with_context(|| format!("Invalid JSON path: \"{}\"", path))?;
|
||||
|
@ -475,6 +600,7 @@ pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
|
|||
let mut unofficial: HashMap<u8, CardSet> = HashMap::new();
|
||||
let mut official_meta: Vec<CardPackMeta> = vec![];
|
||||
let mut unofficial_meta: Vec<CardPackMeta> = vec![];
|
||||
let mut white_cards_by_id = HashMap::<String, Arc<CardWhiteWithID>>::new();
|
||||
|
||||
// Unpack the json
|
||||
for sets in jayson {
|
||||
|
@ -496,10 +622,15 @@ pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
|
|||
pack = Some(white[0].pack);
|
||||
let mut white_buf = vec![];
|
||||
for card in sets.white.unwrap() {
|
||||
white_buf.push(Arc::new(CardWhiteWithID {
|
||||
uuid: Uuid::now_v7(),
|
||||
let uuid = Uuid::now_v7();
|
||||
|
||||
let new_card = Arc::new(CardWhiteWithID {
|
||||
uuid,
|
||||
text: card.text,
|
||||
}));
|
||||
});
|
||||
|
||||
white_cards_by_id.insert(uuid.to_string(), new_card.clone());
|
||||
white_buf.push(new_card);
|
||||
}
|
||||
newset.white = Some(white_buf);
|
||||
}
|
||||
|
@ -555,5 +686,5 @@ pub fn load_cards_from_json(path: &str) -> Result<(CardPacks, CardPacksMeta)> {
|
|||
unofficial_meta,
|
||||
};
|
||||
|
||||
Ok((packs, packs_meta))
|
||||
Ok((packs, packs_meta, white_cards_by_id))
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ pub mod websocket;
|
|||
/// User
|
||||
#[derive(Debug)]
|
||||
pub struct User {
|
||||
pub uuid: Uuid,
|
||||
pub uuid: String,
|
||||
pub name: String,
|
||||
pub tx: Sender<String>,
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ impl User {
|
|||
/// Create a new user object from incoming data
|
||||
pub fn new(name: String, tx: Sender<String>) -> User {
|
||||
User {
|
||||
uuid: Uuid::now_v7(),
|
||||
uuid: Uuid::now_v7().to_string(),
|
||||
name,
|
||||
tx,
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ pub fn load_names(path: &str) -> Result<Vec<String>> {
|
|||
|
||||
// Our shared state
|
||||
pub struct AppState {
|
||||
pub white_cards_by_id: HashMap<String, Arc<CardWhiteWithID>>,
|
||||
pub broadcast_tx: broadcast::Sender<String>,
|
||||
pub users_tx: mpsc::Sender<UserHandlerMessage>,
|
||||
pub messages_tx: mpsc::Sender<(SocketAddr, Message)>,
|
||||
|
@ -67,7 +68,7 @@ pub struct AppState {
|
|||
pub first_names: Vec<String>,
|
||||
pub last_names: Vec<String>,
|
||||
pub reserved_names: RwLock<HashSet<String>>,
|
||||
pub users_by_id: RwLock<HashMap<Uuid, Arc<RwLock<User>>>>,
|
||||
pub users_by_id: RwLock<HashMap<String, Arc<RwLock<User>>>>,
|
||||
pub online_users: RwLock<HashMap<SocketAddr, Arc<RwLock<User>>>>,
|
||||
pub offline_users: RwLock<HashMap<String, Arc<RwLock<User>>>>,
|
||||
pub packs: CardPacks,
|
||||
|
|
|
@ -14,7 +14,6 @@ use tower::ServiceBuilder;
|
|||
use tower_http::{compression::CompressionLayer, services::ServeDir};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
use user_handler::UserHandler;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
|
@ -35,13 +34,14 @@ async fn main() -> Result<()> {
|
|||
let first_names = load_names("data/first.txt")?;
|
||||
let last_names = load_names("data/last.txt")?;
|
||||
let reserved_names = RwLock::new(HashSet::<String>::new());
|
||||
let users_by_id = RwLock::new(HashMap::<Uuid, Arc<RwLock<User>>>::new());
|
||||
let users_by_id = RwLock::new(HashMap::<String, Arc<RwLock<User>>>::new());
|
||||
let online_users = RwLock::new(HashMap::<SocketAddr, Arc<RwLock<User>>>::new());
|
||||
let offline_users = RwLock::new(HashMap::<String, Arc<RwLock<User>>>::new());
|
||||
let (packs, packs_meta) = load_cards_from_json("data/cah-cards-full.json")?;
|
||||
let (packs, packs_meta, white_cards_by_id) = load_cards_from_json("data/cah-cards-full.json")?;
|
||||
let games = RwLock::new(HashMap::new());
|
||||
|
||||
let app_state = Arc::new(AppState {
|
||||
white_cards_by_id,
|
||||
broadcast_tx,
|
||||
users_tx,
|
||||
messages_tx,
|
||||
|
@ -65,7 +65,8 @@ async fn main() -> Result<()> {
|
|||
}
|
||||
});
|
||||
|
||||
// TODO: Make an outgoing message handler handler
|
||||
// TODO: Restart handler threads if they crash
|
||||
// TODO: Make an outgoing message handler handler?
|
||||
|
||||
// Spawn task to handle User things
|
||||
let user_handler = UserHandler::new(app_state.clone());
|
||||
|
|
|
@ -83,6 +83,16 @@ impl MessageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
_judge_decision
|
||||
if let Ok(judge_request) = from_str::<JudgeDecisionRequest>(&text) =>
|
||||
{
|
||||
self.state
|
||||
.games_tx
|
||||
.send(JudgeDecision(judge_request, addr))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
_ => tracing::debug!("Unhandled text from {}", addr),
|
||||
},
|
||||
|
||||
|
|
|
@ -27,12 +27,18 @@ pub enum UserHandlerMessage {
|
|||
addr: SocketAddr,
|
||||
message: SendUserMessage,
|
||||
},
|
||||
DmUserId {
|
||||
id: String,
|
||||
message: SendUserMessage,
|
||||
},
|
||||
}
|
||||
|
||||
/// Types of messages that can be sent to a user as a DM
|
||||
// TODO: try to eliminate this extra step
|
||||
pub enum SendUserMessage {
|
||||
SendUserUpdate(UserUpdate),
|
||||
SendChatMessage(ChatMessage),
|
||||
SendJudgeRound(JudgeRound),
|
||||
}
|
||||
|
||||
impl UserHandler {
|
||||
|
@ -50,9 +56,43 @@ impl UserHandler {
|
|||
}
|
||||
UserLogIn { username, addr } => self.login(username, addr).await,
|
||||
DmUserAddr { addr, message } => self.send_message_addr(addr, message).await,
|
||||
DmUserId { id, message } => self.send_message_id(id, message).await,
|
||||
}
|
||||
}
|
||||
|
||||
/// Send message direct to a single user via user id
|
||||
async fn send_message_id(&self, id: String, message: SendUserMessage) {
|
||||
let tx = self
|
||||
.state
|
||||
.users_by_id
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&id)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.tx
|
||||
.clone();
|
||||
|
||||
// TODO: this feels messy
|
||||
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()
|
||||
}
|
||||
SendJudgeRound(message) => {
|
||||
let msg = to_string::<JudgeRound>(&message).unwrap();
|
||||
tx.send(msg).await.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Combine ^v these
|
||||
|
||||
/// Send message direct to a single user via addr
|
||||
async fn send_message_addr(&self, addr: SocketAddr, message: SendUserMessage) {
|
||||
let tx = self
|
||||
|
@ -75,6 +115,10 @@ impl UserHandler {
|
|||
let msg = to_string::<ChatMessage>(&message).unwrap();
|
||||
tx.send(msg).await.unwrap()
|
||||
}
|
||||
SendJudgeRound(message) => {
|
||||
let msg = to_string::<JudgeRound>(&message).unwrap();
|
||||
tx.send(msg).await.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue