reduce potential explosions and add error messages
This commit is contained in:
parent
13ba4944ca
commit
1550772995
2 changed files with 194 additions and 260 deletions
|
@ -46,123 +46,101 @@ impl GameHandler {
|
|||
/// Delete game
|
||||
async fn delete_game(&self, request: GameDeleteRequest) {
|
||||
// TODO: add auth lol
|
||||
let _ = self
|
||||
if self
|
||||
.state
|
||||
.games
|
||||
.write()
|
||||
.unwrap()
|
||||
.remove(&request.delete_game_id)
|
||||
.unwrap();
|
||||
|
||||
// Broadcast game browser update
|
||||
self.state
|
||||
.broadcast_tx
|
||||
.send(meta_games_browser_update(&self.state))
|
||||
.unwrap();
|
||||
.is_some()
|
||||
{
|
||||
// Broadcast game browser update
|
||||
self.state
|
||||
.broadcast_tx
|
||||
.send(meta_games_browser_update(&self.state))
|
||||
.unwrap();
|
||||
} else {
|
||||
tracing::error!("User tried to delete a nonexistent game!");
|
||||
}
|
||||
}
|
||||
|
||||
/// Process judging
|
||||
async fn handle_judging(&self, request: JudgeDecisionRequest, addr: SocketAddr) {
|
||||
// Get pointers
|
||||
let player_user_id = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.uuid
|
||||
.to_string();
|
||||
if let Some(this_game) = self.state.games.read().unwrap().get(&request.game_id) {
|
||||
if let Some(player_user) = self.state.online_users.read().unwrap().get(&addr) {
|
||||
let player_user_id = player_user.read().unwrap().uuid.to_string();
|
||||
let game_id = request.game_id.to_string();
|
||||
|
||||
let this_game = self
|
||||
.state
|
||||
.games
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&request.game_id)
|
||||
.unwrap()
|
||||
.clone();
|
||||
// Send to game
|
||||
this_game
|
||||
.write()
|
||||
.unwrap()
|
||||
.judge_round(request, player_user_id);
|
||||
|
||||
// Send to game
|
||||
this_game
|
||||
.write()
|
||||
.unwrap()
|
||||
.judge_round(request.clone(), player_user_id.clone());
|
||||
|
||||
let this_game_id = this_game.read().unwrap().uuid.to_string();
|
||||
self.send_game_state_update(this_game_id).await
|
||||
self.send_game_state_update(game_id);
|
||||
} else {
|
||||
tracing::error!("Received judge request for nonexistent judge player!");
|
||||
}
|
||||
} else {
|
||||
tracing::error!("Received judge request for nonexistent game!");
|
||||
}
|
||||
}
|
||||
|
||||
/// Process player move request
|
||||
async fn handle_player_move(&self, request: PlayerMoveRequest, addr: SocketAddr) {
|
||||
// Get pointers
|
||||
let player_user_id = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.uuid
|
||||
.to_string();
|
||||
if let Some(this_game) = self.state.games.read().unwrap().get(&request.game_id) {
|
||||
if let Some(player_user) = self.state.online_users.read().unwrap().get(&addr) {
|
||||
let player_user_id = player_user.read().unwrap().uuid.to_string();
|
||||
|
||||
let this_game = self
|
||||
.state
|
||||
.games
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&request.game_id)
|
||||
.unwrap()
|
||||
.clone();
|
||||
// Do the stuff
|
||||
match this_game
|
||||
.write()
|
||||
.unwrap()
|
||||
.player_move(request, player_user_id)
|
||||
{
|
||||
Err(err) => {
|
||||
let message = ChatMessage { text: err };
|
||||
let tx = self.state.users_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
let _ = tx.send(DmUser(SendChatMessage(message), Addr(addr))).await;
|
||||
})
|
||||
}
|
||||
Ok(None) => tokio::spawn(async move { tracing::debug!("None") }),
|
||||
Ok(Some((judge_round, czar_id))) => {
|
||||
let tx = self.state.users_tx.clone();
|
||||
|
||||
// Do the stuff
|
||||
match this_game
|
||||
.write()
|
||||
.unwrap()
|
||||
.player_move(request, player_user_id)
|
||||
{
|
||||
Err(err) => {
|
||||
let message = ChatMessage { text: err };
|
||||
let tx = self.state.users_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
let _ = tx.send(DmUser(SendChatMessage(message), Addr(addr))).await;
|
||||
})
|
||||
tokio::spawn(async move {
|
||||
let _ = tx
|
||||
.send(DmUser(SendJudgeRound(judge_round), Id(czar_id)))
|
||||
.await;
|
||||
})
|
||||
}
|
||||
};
|
||||
} else {
|
||||
tracing::error!("Nonexistent player tried to submit move for game!");
|
||||
}
|
||||
Ok(None) => tokio::spawn(async move { tracing::debug!("None") }),
|
||||
Ok(Some((judge_round, czar_id))) => {
|
||||
let tx = self.state.users_tx.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let _ = tx
|
||||
.send(DmUser(SendJudgeRound(judge_round), Id(czar_id)))
|
||||
.await;
|
||||
})
|
||||
}
|
||||
};
|
||||
} else {
|
||||
tracing::error!("Player tried to submit move for nonexistent game!");
|
||||
}
|
||||
}
|
||||
|
||||
/// Puts a user in a game
|
||||
async fn join_game(&self, id: String, addr: SocketAddr) {
|
||||
// Get pointers
|
||||
let this_game = self.state.games.read().unwrap().get(&id).unwrap().clone();
|
||||
let this_user = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
// Create player
|
||||
this_game.write().unwrap().create_player(this_user);
|
||||
if let Some(this_game) = self.state.games.read().unwrap().get(&id) {
|
||||
if let Some(this_user) = self.state.online_users.read().unwrap().get(&addr) {
|
||||
// Create player
|
||||
this_game.write().unwrap().create_player(this_user.clone());
|
||||
} else {
|
||||
tracing::error!("Tried to add a nonexistent user to game!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
tracing::error!("User tried to join a nonexistent game!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Send updates for all players
|
||||
self.send_game_state_update(id).await;
|
||||
self.send_game_state_update(id);
|
||||
|
||||
// Broadcast game browser update
|
||||
self.state
|
||||
|
@ -178,57 +156,52 @@ impl GameHandler {
|
|||
}
|
||||
|
||||
/// Send game state update for all players of a game
|
||||
async fn send_game_state_update(&self, game_id: String) {
|
||||
let this_game = self
|
||||
.state
|
||||
.games
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&game_id)
|
||||
.unwrap()
|
||||
.clone();
|
||||
fn send_game_state_update(&self, game_id: String) {
|
||||
if let Some(this_game) = self.state.games.read().unwrap().get(&game_id) {
|
||||
let players = this_game
|
||||
.read()
|
||||
.unwrap()
|
||||
.players
|
||||
.values()
|
||||
.map(|player| GamePlayerMeta {
|
||||
name: player.user.read().unwrap().name.clone(),
|
||||
score: player.black.len(),
|
||||
})
|
||||
.collect::<Vec<GamePlayerMeta>>();
|
||||
|
||||
let players = this_game
|
||||
.read()
|
||||
.unwrap()
|
||||
.players
|
||||
.values()
|
||||
.map(|player| GamePlayerMeta {
|
||||
name: player.user.read().unwrap().name.clone(),
|
||||
score: player.black.len(),
|
||||
})
|
||||
.collect::<Vec<GamePlayerMeta>>();
|
||||
for player in this_game.read().unwrap().players.values() {
|
||||
// Create update for user's game view
|
||||
let meta = GameStateMeta {
|
||||
uuid: game_id.clone(),
|
||||
name: this_game.read().unwrap().name.clone(),
|
||||
host: this_game.read().unwrap().host.read().unwrap().name.clone(),
|
||||
players: players.clone(),
|
||||
czar: this_game.read().unwrap().czar.read().unwrap().name.clone(),
|
||||
black: (
|
||||
this_game.read().unwrap().current_black.text.clone(),
|
||||
this_game.read().unwrap().current_black.pick,
|
||||
),
|
||||
white: player
|
||||
.white
|
||||
.iter()
|
||||
.map(|card| WhiteCardMeta {
|
||||
uuid: card.uuid.to_string(),
|
||||
text: card.text.clone(),
|
||||
})
|
||||
.collect(),
|
||||
packs: this_game.read().unwrap().packs.clone(),
|
||||
white_count: this_game.read().unwrap().white.len(),
|
||||
black_count: this_game.read().unwrap().black.len(),
|
||||
white_discard_count: this_game.read().unwrap().white_discard.len(),
|
||||
};
|
||||
|
||||
for player in this_game.read().unwrap().players.values() {
|
||||
// Create update for user's game view
|
||||
let meta = GameStateMeta {
|
||||
uuid: game_id.clone(),
|
||||
name: this_game.read().unwrap().name.clone(),
|
||||
host: this_game.read().unwrap().host.read().unwrap().name.clone(),
|
||||
players: players.clone(),
|
||||
czar: this_game.read().unwrap().czar.read().unwrap().name.clone(),
|
||||
black: (
|
||||
this_game.read().unwrap().current_black.text.clone(),
|
||||
this_game.read().unwrap().current_black.pick,
|
||||
),
|
||||
white: player
|
||||
.white
|
||||
.iter()
|
||||
.map(|card| WhiteCardMeta {
|
||||
uuid: card.uuid.to_string(),
|
||||
text: card.text.clone(),
|
||||
})
|
||||
.collect(),
|
||||
packs: this_game.read().unwrap().packs.clone(),
|
||||
white_count: this_game.read().unwrap().white.len(),
|
||||
black_count: this_game.read().unwrap().black.len(),
|
||||
white_discard_count: this_game.read().unwrap().white_discard.len(),
|
||||
};
|
||||
|
||||
// Send user's update
|
||||
let msg = serde_json::to_string(&meta).unwrap();
|
||||
let user_tx = player.user.read().unwrap().tx.clone();
|
||||
tokio::spawn(async move { user_tx.send(msg).await });
|
||||
// Send user's update
|
||||
let msg = serde_json::to_string(&meta).unwrap();
|
||||
let user_tx = player.user.read().unwrap().tx.clone();
|
||||
tokio::spawn(async move { user_tx.send(msg).await });
|
||||
}
|
||||
} else {
|
||||
tracing::error!("Attempted to create game state update for nonexistent game!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,49 +215,43 @@ impl GameHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get host pointer
|
||||
let host = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.clone();
|
||||
if let Some(host) = self.state.online_users.read().unwrap().get(&addr) {
|
||||
// Create manifest
|
||||
let manifest = NewGameManifest {
|
||||
name: new_game.name,
|
||||
host: host.clone(),
|
||||
packs: new_game.packs,
|
||||
};
|
||||
|
||||
// Create manifest
|
||||
let manifest = NewGameManifest {
|
||||
name: new_game.name,
|
||||
host: host.clone(),
|
||||
packs: new_game.packs,
|
||||
};
|
||||
// Create game using manifest
|
||||
let mut new_game_object = Game::new(self.state.clone(), manifest);
|
||||
|
||||
// Create game using manifest
|
||||
let mut new_game_object = Game::new(self.state.clone(), manifest);
|
||||
// Don't forget to create the host player!!!
|
||||
new_game_object.create_player(host.clone());
|
||||
|
||||
// Don't forget to create the host player!!!
|
||||
new_game_object.create_player(host.clone());
|
||||
let game_id = new_game_object.uuid.to_string();
|
||||
|
||||
let game_id = new_game_object.uuid.to_string();
|
||||
// Add game to active list
|
||||
self.state.games.write().unwrap().insert(
|
||||
new_game_object.uuid.to_string(),
|
||||
Arc::new(RwLock::new(new_game_object)),
|
||||
);
|
||||
|
||||
// Add game to active list
|
||||
self.state.games.write().unwrap().insert(
|
||||
new_game_object.uuid.to_string(),
|
||||
Arc::new(RwLock::new(new_game_object)),
|
||||
);
|
||||
self.send_game_state_update(game_id);
|
||||
|
||||
self.send_game_state_update(game_id).await;
|
||||
// Broadcast game browser update
|
||||
self.state
|
||||
.broadcast_tx
|
||||
.send(meta_games_browser_update(&self.state))
|
||||
.unwrap();
|
||||
|
||||
// Broadcast game browser update
|
||||
self.state
|
||||
.broadcast_tx
|
||||
.send(meta_games_browser_update(&self.state))
|
||||
.unwrap();
|
||||
|
||||
// Broadcast server meta update
|
||||
self.state
|
||||
.broadcast_tx
|
||||
.send(meta_server_summary_update(&self.state))
|
||||
.unwrap();
|
||||
// Broadcast server meta update
|
||||
self.state
|
||||
.broadcast_tx
|
||||
.send(meta_server_summary_update(&self.state))
|
||||
.unwrap();
|
||||
} else {
|
||||
tracing::error!("Attempted to create game for nonexistent player!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ impl UserHandler {
|
|||
tx = user.read().unwrap().tx.clone();
|
||||
} else {
|
||||
tracing::error!("Attempted to send message to invalid user id!");
|
||||
// TODO: User can still be offline causing send to fail. This is suppressed
|
||||
// below
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +79,7 @@ impl UserHandler {
|
|||
}
|
||||
|
||||
// Serialize and send message
|
||||
// TODO: Send failures are suppressed
|
||||
match message {
|
||||
SendUserUpdate(message) => {
|
||||
let msg = to_string::<UserUpdate>(&message).unwrap();
|
||||
|
@ -99,7 +102,7 @@ impl UserHandler {
|
|||
let new_user = Arc::new(RwLock::new(user));
|
||||
|
||||
// Notify client of new username
|
||||
tx.send(user_client_self_update(&new_user)).await.unwrap();
|
||||
let _ = tx.send(user_client_self_update(&new_user)).await;
|
||||
|
||||
// Register uuid
|
||||
self.state
|
||||
|
@ -116,12 +119,8 @@ impl UserHandler {
|
|||
.insert(addr, new_user.clone());
|
||||
|
||||
// Hydrate client
|
||||
tx.send(meta_games_browser_update(&self.state))
|
||||
.await
|
||||
.unwrap();
|
||||
tx.send(meta_new_game_card_packs(&self.state))
|
||||
.await
|
||||
.unwrap();
|
||||
let _ = tx.send(meta_games_browser_update(&self.state)).await;
|
||||
let _ = tx.send(meta_new_game_card_packs(&self.state)).await;
|
||||
|
||||
// Broadcast new user's existence
|
||||
// TODO: this should probably be combined and sent as one
|
||||
|
@ -136,24 +135,21 @@ impl UserHandler {
|
|||
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...
|
||||
tx.send(meta_motd()).await.unwrap();
|
||||
let _ = tx.send(meta_motd()).await;
|
||||
}
|
||||
|
||||
/// Handle user login
|
||||
async fn login(&self, request: UserLogInRequest, addr: SocketAddr) {
|
||||
let broadcast_tx = self.state.broadcast_tx.clone();
|
||||
let new_name = request.username.clone();
|
||||
let old_name = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.name
|
||||
.clone();
|
||||
let old_name;
|
||||
|
||||
if let Some(user) = self.state.online_users.read().unwrap().get(&addr) {
|
||||
old_name = user.read().unwrap().name.clone();
|
||||
} else {
|
||||
tracing::error!("Nonexistent user attempting login");
|
||||
return;
|
||||
}
|
||||
|
||||
// Resume user's old session if they exist as offline
|
||||
if self
|
||||
|
@ -163,42 +159,25 @@ impl UserHandler {
|
|||
.unwrap()
|
||||
.contains_key(&new_name)
|
||||
{
|
||||
let buf;
|
||||
// Copy over new tx
|
||||
self.state
|
||||
.offline_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&new_name)
|
||||
.unwrap()
|
||||
.write()
|
||||
.unwrap()
|
||||
.tx = self
|
||||
.state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.tx
|
||||
.clone();
|
||||
if let Some(online_user) = self.state.online_users.write().unwrap().remove(&addr) {
|
||||
if let Some(offline_user) =
|
||||
self.state.offline_users.write().unwrap().remove(&new_name)
|
||||
{
|
||||
offline_user.write().unwrap().tx = online_user.write().unwrap().tx.clone();
|
||||
buf = offline_user;
|
||||
} else {
|
||||
tracing::error!("Error copying tx to new user: Can't find offline user!");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
tracing::error!("Error copying tx to new user: Can't find online user!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Move offline user object to online
|
||||
self.state
|
||||
.online_users
|
||||
.write()
|
||||
.unwrap()
|
||||
.insert(
|
||||
addr,
|
||||
self.state
|
||||
.offline_users
|
||||
.write()
|
||||
.unwrap()
|
||||
.remove(&new_name)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
self.state.online_users.write().unwrap().insert(addr, buf);
|
||||
|
||||
// Send welcome back messages
|
||||
let msg = format! {
|
||||
|
@ -241,15 +220,12 @@ impl UserHandler {
|
|||
.insert(new_name.clone());
|
||||
|
||||
// Change user's name
|
||||
self.state
|
||||
.online_users
|
||||
.write()
|
||||
.unwrap()
|
||||
.get_mut(&addr)
|
||||
.unwrap()
|
||||
.write()
|
||||
.unwrap()
|
||||
.change_name(request.username);
|
||||
if let Some(user) = self.state.online_users.write().unwrap().get_mut(&addr) {
|
||||
user.write().unwrap().change_name(request.username);
|
||||
} else {
|
||||
tracing::error!("Error updating username: Can't find user!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Send chat updates
|
||||
let msg = format! {
|
||||
|
@ -257,9 +233,8 @@ impl UserHandler {
|
|||
old_name,
|
||||
new_name
|
||||
};
|
||||
broadcast_tx
|
||||
.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap())
|
||||
.unwrap();
|
||||
let _ =
|
||||
broadcast_tx.send(to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap());
|
||||
}
|
||||
|
||||
// Send the user their new name
|
||||
|
@ -270,12 +245,9 @@ impl UserHandler {
|
|||
Addr(addr),
|
||||
)
|
||||
.await;
|
||||
|
||||
// Send client updates
|
||||
broadcast_tx
|
||||
.send(meta_games_browser_update(&self.state))
|
||||
.unwrap();
|
||||
broadcast_tx.send(meta_chat_update(&self.state)).unwrap();
|
||||
let _ = broadcast_tx.send(meta_games_browser_update(&self.state));
|
||||
let _ = broadcast_tx.send(meta_chat_update(&self.state));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,18 +319,13 @@ pub fn meta_games_browser_update(state: &Arc<AppState>) -> String {
|
|||
|
||||
/// Generate chatroom join announcement
|
||||
pub fn meta_announce_user_join(state: &Arc<AppState>, addr: &SocketAddr) -> String {
|
||||
let msg = format!(
|
||||
"{} joined.",
|
||||
state
|
||||
.online_users
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(addr)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
.name
|
||||
);
|
||||
let msg = format!("{} joined.", {
|
||||
if let Some(user) = state.online_users.read().unwrap().get(addr) {
|
||||
user.read().unwrap().name.clone()
|
||||
} else {
|
||||
return Default::default();
|
||||
}
|
||||
});
|
||||
|
||||
tracing::debug!("{}", &msg);
|
||||
to_string::<ChatMessage>(&ChatMessage { text: msg }).unwrap()
|
||||
|
|
Loading…
Add table
Reference in a new issue