diff --git a/src/server.rs b/src/server.rs index 6f1781a..1164b92 100644 --- a/src/server.rs +++ b/src/server.rs @@ -624,9 +624,11 @@ impl Server { let _ = send(&player.connection, "TOURNAMENT:END"); } + let tournament_winner = tourney.read().await.get_winner().unwrap(); *tournament_guard = None; self.broadcast("TOURNAMENT:END").await; + self.broadcast(&format!("TOURNAMENT:WINNER:{}", tournament_winner)).await; } } } @@ -908,9 +910,11 @@ impl Server { let _ = send(&player.connection, "TOURNAMENT:END"); } + let tournament_winner = tourney.read().await.get_winner().unwrap(); *tournament_guard = None; self.broadcast("TOURNAMENT:END").await; + self.broadcast(&format!("TOURNAMENT:WINNER:{}", tournament_winner)).await; } } Ok(()) @@ -1043,9 +1047,11 @@ impl Server { let _ = send(&player.connection, "TOURNAMENT:END"); } + let tournament_winner = tourney.read().await.get_winner().unwrap(); *tournament_guard = None; self.broadcast("TOURNAMENT:END").await; + self.broadcast(&format!("TOURNAMENT:WINNER:{}", tournament_winner)).await; } } } else { @@ -1144,6 +1150,16 @@ impl Server { msg += "false"; } } + "TOURNAMENT_DATA" => { + let tournament = self.tournament.read().await.clone(); + if tournament.is_some() { + let tourney_guard = tournament.as_ref().unwrap().read().await; + let data = tourney_guard.get_data(); + if let Some(data) = data { + msg += &data; + } + } + } "MOVE_WAIT" => { let wait_time = *self.waiting_timeout.read().await as f64 / 1000f64; msg += wait_time.to_string().as_str(); diff --git a/src/tournaments/knockout_bracket.rs b/src/tournaments/knockout_bracket.rs index c248923..6eaebb8 100644 --- a/src/tournaments/knockout_bracket.rs +++ b/src/tournaments/knockout_bracket.rs @@ -21,6 +21,7 @@ pub struct KnockoutBracket { pub matches: Matches, pub observers: Observers, pub usernames: Vec, + pub data: Vec>, } impl KnockoutBracket { @@ -112,6 +113,7 @@ impl Tournament for KnockoutBracket { matches: server.matches.clone(), observers: server.observers.clone(), usernames: ready_players.to_vec(), + data: Vec::new(), } } @@ -125,6 +127,7 @@ impl Tournament for KnockoutBracket { } if self.blitz_round_robin.completed && !self.started { + self.started = true; *server.waiting_timeout.write().await = self.previous_wait; let mut players = Vec::new(); @@ -132,25 +135,29 @@ impl Tournament for KnockoutBracket { players.push((player.0.clone(), player.1, false)); } - players.sort_by(|a, b| b.1.cmp(&a.1)); + players.sort_by(|a, b| a.1.cmp(&b.1)); self.players = players; for player in &self.players { self.pairings.push(player.0.clone()); } + self.data.push(self.pairings.clone()); self.create_matches().await; - - self.started = true; + broadcast_message(&self.observers, &format!("GET:TOURNAMENT_DATA:{}", self.get_data().unwrap())).await; return; } - if self.pairings.len() == 1 { - self.completed = true; - } else { + if self.started { self.pairings.retain(|p| !p.is_empty()); - self.create_matches().await; - } + if self.pairings.len() == 1 { + self.completed = true; + } else { + self.data.push(self.pairings.clone()); + self.create_matches().await; + broadcast_message(&self.observers, &format!("GET:TOURNAMENT_DATA:{}", self.get_data().unwrap())).await; + } + } } async fn start(&mut self, server: &Server) { @@ -322,6 +329,36 @@ impl Tournament for KnockoutBracket { fn get_players(&self) -> Vec { self.usernames.clone() } + + fn get_winner(&self) -> Option { + if self.completed { + return Some(self.pairings[0].clone()); + } + + None + } + + fn get_data(&self) -> Option { + if !self.started { + return None; + } + + let mut message = String::new(); + for round in self.data.iter() { + for player in round.iter() { + message += player; + message += ","; + } + message.pop(); + message.push('|'); + } + + if self.data.len() > 0 { + message.pop(); + } + + Some(message) + } fn get_type(&self) -> String { "KnockoutBracket".to_string() diff --git a/src/tournaments/mod.rs b/src/tournaments/mod.rs index ba8881e..fcd757e 100644 --- a/src/tournaments/mod.rs +++ b/src/tournaments/mod.rs @@ -25,5 +25,7 @@ pub trait Tournament { fn contains_player(&self, username: String) -> bool; fn is_completed(&self) -> bool; fn get_players(&self) -> Vec; + fn get_winner(&self) -> Option; + fn get_data(&self) -> Option; fn get_type(&self) -> String; } diff --git a/src/tournaments/round_robin.rs b/src/tournaments/round_robin.rs index 5c3a601..7e8f275 100644 --- a/src/tournaments/round_robin.rs +++ b/src/tournaments/round_robin.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use async_trait::async_trait; -use tracing::info; use crate::{server::Server, *}; @@ -122,8 +121,6 @@ impl Tournament for RoundRobin { } async fn inform_winner(&mut self, winner: String, match_id: u32, _: String, _: String) { - info!("RoundRobin: told winner was \"{}\"", winner); - if winner.is_empty() { return; } @@ -215,6 +212,28 @@ impl Tournament for RoundRobin { fn get_players(&self) -> Vec { self.usernames.clone() } + + fn get_winner(&self) -> Option { + if !self.is_completed() { + return None; + } + + let mut best_score = 0; + let mut winner = None; + + for (_, (username, score)) in self.players.iter() { + if *score > best_score { + best_score = *score; + winner = Some(username.clone()); + } + } + + winner + } + + fn get_data(&self) -> Option { + None + } fn get_type(&self) -> String { "RoundRobin".to_string()