feat: remove the need for constant polling data
This commit is contained in:
@@ -326,6 +326,8 @@ async fn handle_connection(
|
||||
sd.clients.write().await.remove(&username);
|
||||
sd.usernames.write().await.remove(&addr);
|
||||
|
||||
sd.broadcast(&format!("DISCONNECT:{}", username)).await;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,21 @@ impl Server {
|
||||
) -> Result<(), anyhow::Error> {
|
||||
if requested_username.is_empty() {
|
||||
return Err(anyhow::anyhow!(format!(
|
||||
"ERROR:INVALID:ID:{}",
|
||||
"ERROR:INVALID:CONNECT:{}",
|
||||
requested_username
|
||||
)));
|
||||
}
|
||||
|
||||
if requested_username.chars().any(|c| matches!(c, ':' | ',' | '|') || c.is_control()) {
|
||||
return Err(anyhow::anyhow!(format!(
|
||||
"ERROR:INVALID:CONNECT:{}",
|
||||
requested_username
|
||||
)));
|
||||
}
|
||||
|
||||
if requested_username == SERVER_PLAYER_USERNAME {
|
||||
return Err(anyhow::anyhow!(format!(
|
||||
"ERROR:INVALID:ID:{}",
|
||||
"ERROR:INVALID:CONNECT:{}",
|
||||
requested_username
|
||||
)));
|
||||
}
|
||||
@@ -66,7 +73,7 @@ impl Server {
|
||||
let existing_client = clients_guard.get(&requested_username).cloned();
|
||||
if existing_client.is_some() && !reconnecting {
|
||||
return Err(anyhow::anyhow!(format!(
|
||||
"ERROR:INVALID:ID:{}",
|
||||
"ERROR:INVALID:CONNECT:{}",
|
||||
requested_username
|
||||
)));
|
||||
}
|
||||
@@ -81,12 +88,14 @@ impl Server {
|
||||
self.clients.write().await.insert(
|
||||
requested_username.clone(),
|
||||
Arc::new(RwLock::new(Client::new(
|
||||
requested_username,
|
||||
requested_username.clone(),
|
||||
tx.clone(),
|
||||
addr.to_string().parse()?,
|
||||
))),
|
||||
);
|
||||
|
||||
self.broadcast(&format!("CONNECT:{}", requested_username)).await;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -217,6 +226,7 @@ impl Server {
|
||||
self.clients.write().await.remove(&username);
|
||||
self.usernames.write().await.remove(&addr);
|
||||
let _ = send(&tx, "DISCONNECT:ACK");
|
||||
self.broadcast(&format!("DISCONNECT:{}", username)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -264,6 +274,7 @@ impl Server {
|
||||
let _ = send(&tx, "READY:ACK");
|
||||
drop(client);
|
||||
drop(clients_guard);
|
||||
self.broadcast(&format!("READY:{}:{}", username, true)).await;
|
||||
|
||||
if let Some(opponent_username) = self.find_reservation_opponent(&username).await {
|
||||
let clients_guard = self.clients.read().await;
|
||||
@@ -278,6 +289,14 @@ impl Server {
|
||||
false,
|
||||
)));
|
||||
self.matches.write().await.insert(match_id, new_match.clone());
|
||||
let match_guard = new_match.read().await;
|
||||
self
|
||||
.broadcast(&format!(
|
||||
"GAME:START:{},{},{}",
|
||||
match_id, match_guard.player1, match_guard.player2
|
||||
))
|
||||
.await;
|
||||
drop(match_guard);
|
||||
|
||||
client.ready = false;
|
||||
client.current_match = Some(match_id);
|
||||
@@ -294,6 +313,7 @@ impl Server {
|
||||
opponent.ready = false;
|
||||
opponent.current_match = Some(match_id);
|
||||
opponent.color = !client.color;
|
||||
let opponent_username = opponent.username.clone();
|
||||
|
||||
self
|
||||
.reservations
|
||||
@@ -301,6 +321,12 @@ impl Server {
|
||||
.await
|
||||
.retain(|(p1, p2)| !(p1 == &client.username && p2 == &opponent.username));
|
||||
|
||||
drop(opponent);
|
||||
drop(client);
|
||||
drop(clients_guard);
|
||||
self.broadcast(&format!("READY:{}:{}", username, false)).await;
|
||||
self.broadcast(&format!("READY:{}:{}", opponent_username, false)).await;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -316,6 +342,15 @@ impl Server {
|
||||
is_demo_mode,
|
||||
)));
|
||||
self.matches.write().await.insert(match_id, new_match.clone());
|
||||
let match_guard = new_match.read().await;
|
||||
self
|
||||
.broadcast(&format!(
|
||||
"GAME:START:{},{},{}",
|
||||
match_id, match_guard.player1, match_guard.player2
|
||||
))
|
||||
.await;
|
||||
drop(match_guard);
|
||||
|
||||
client.ready = false;
|
||||
client.current_match = Some(match_id);
|
||||
client.color = if new_match.read().await.player1 == username {
|
||||
@@ -355,6 +390,9 @@ impl Server {
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
drop(client);
|
||||
self.broadcast(&format!("READY:{}:{}", username, false)).await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1202,8 +1240,17 @@ impl Server {
|
||||
false,
|
||||
)));
|
||||
self.matches.write().await.insert(match_id, new_match.clone());
|
||||
let match_guard = new_match.read().await;
|
||||
self
|
||||
.broadcast(&format!(
|
||||
"GAME:START:{},{},{}",
|
||||
match_id, match_guard.player1, match_guard.player2
|
||||
))
|
||||
.await;
|
||||
drop(match_guard);
|
||||
|
||||
player1.ready = false;
|
||||
let player1_name = player1.username.clone();
|
||||
player1.current_match = Some(match_id);
|
||||
player1.color = if new_match.read().await.player1 == player1_username {
|
||||
let _ = send(&tx, "GAME:START:1");
|
||||
@@ -1216,6 +1263,7 @@ impl Server {
|
||||
};
|
||||
|
||||
player2.ready = false;
|
||||
let player2_name = player2.username.clone();
|
||||
player2.current_match = Some(match_id);
|
||||
player2.color = !player1.color;
|
||||
|
||||
@@ -1224,6 +1272,12 @@ impl Server {
|
||||
.write()
|
||||
.await
|
||||
.retain(|(p1, p2)| !(p1 == &player1_username && p2 == &player2_username));
|
||||
|
||||
drop(player2);
|
||||
drop(player1);
|
||||
drop(clients_guard);
|
||||
self.broadcast(&format!("READY:{}:{}", player1_name, false)).await;
|
||||
self.broadcast(&format!("READY:{}:{}", player2_name, false)).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ pub struct KnockoutBracket {
|
||||
pub started: bool,
|
||||
pub clients: Clients,
|
||||
pub matches: Matches,
|
||||
pub observers: Observers,
|
||||
pub usernames: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -39,12 +40,16 @@ impl KnockoutBracket {
|
||||
player2_username.clone(),
|
||||
false,
|
||||
)));
|
||||
|
||||
let match_guard = new_match.read().await;
|
||||
let mut player1 = clients_guard.get(&player1_username).unwrap().write().await;
|
||||
|
||||
let mut player1 = clients_guard.get(&player1_username).unwrap().write().await;
|
||||
player1.current_match = Some(match_id);
|
||||
player1.ready = false;
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!("READY:{}:{}", player1.username.clone(), false),
|
||||
)
|
||||
.await;
|
||||
|
||||
if match_guard.player1 == player1_username {
|
||||
player1.color = Color::Red;
|
||||
@@ -53,13 +58,16 @@ impl KnockoutBracket {
|
||||
player1.color = Color::Yellow;
|
||||
let _ = send(&player1.connection, "GAME:START:0");
|
||||
}
|
||||
|
||||
drop(player1);
|
||||
|
||||
let mut player2 = clients_guard.get(&player2_username).unwrap().write().await;
|
||||
|
||||
player2.current_match = Some(match_id);
|
||||
player2.ready = false;
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!("READY:{}:{}", player2.username.clone(), false),
|
||||
)
|
||||
.await;
|
||||
|
||||
if match_guard.player1 == player2_username {
|
||||
player2.color = Color::Red;
|
||||
@@ -68,10 +76,17 @@ impl KnockoutBracket {
|
||||
player2.color = Color::Yellow;
|
||||
let _ = send(&player2.connection, "GAME:START:0");
|
||||
}
|
||||
|
||||
drop(player2);
|
||||
|
||||
self.matches.write().await.insert(match_id, new_match.clone());
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!(
|
||||
"GAME:START:{},{},{}",
|
||||
match_id, match_guard.player1, match_guard.player2
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
i += 2
|
||||
}
|
||||
@@ -95,6 +110,7 @@ impl Tournament for KnockoutBracket {
|
||||
started: false,
|
||||
clients: server.clients.clone(),
|
||||
matches: server.matches.clone(),
|
||||
observers: server.observers.clone(),
|
||||
usernames: ready_players.to_vec(),
|
||||
}
|
||||
}
|
||||
@@ -219,6 +235,7 @@ impl Tournament for KnockoutBracket {
|
||||
|
||||
player1.current_match = Some(match_id);
|
||||
player1.ready = false;
|
||||
let player1_name = player1.username.clone();
|
||||
|
||||
if match_guard.player1 == player1.username {
|
||||
player1.color = Color::Red;
|
||||
@@ -234,6 +251,7 @@ impl Tournament for KnockoutBracket {
|
||||
|
||||
player2.current_match = Some(match_id);
|
||||
player2.ready = false;
|
||||
let player2_name = player2.username.clone();
|
||||
|
||||
if match_guard.player1 == player2.username {
|
||||
player2.color = Color::Red;
|
||||
@@ -245,8 +263,27 @@ impl Tournament for KnockoutBracket {
|
||||
|
||||
drop(player2);
|
||||
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!("READY:{}:{}", player1_name, false),
|
||||
)
|
||||
.await;
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!("READY:{}:{}", player2_name, false),
|
||||
)
|
||||
.await;
|
||||
|
||||
self.current_matches.push(match_id);
|
||||
self.matches.write().await.insert(match_id, new_match.clone());
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!(
|
||||
"GAME:START:{},{},{}",
|
||||
match_id, match_guard.player1, match_guard.player2
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
let mut loser = String::new();
|
||||
|
||||
@@ -16,6 +16,7 @@ pub struct RoundRobin {
|
||||
pub completed: bool,
|
||||
pub current_matches: Vec<ID>,
|
||||
pub usernames: Vec<String>,
|
||||
pub observers: Observers,
|
||||
}
|
||||
|
||||
impl RoundRobin {
|
||||
@@ -39,12 +40,16 @@ impl RoundRobin {
|
||||
)));
|
||||
|
||||
self.current_matches.push(match_id.clone());
|
||||
|
||||
let match_guard = new_match.read().await;
|
||||
let mut player1 = clients_guard.get(&player1_username.0).unwrap().write().await;
|
||||
|
||||
let mut player1 = clients_guard.get(&player1_username.0).unwrap().write().await;
|
||||
player1.current_match = Some(match_id);
|
||||
player1.ready = false;
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!("READY:{}:{}", player1.username.clone(), false),
|
||||
)
|
||||
.await;
|
||||
|
||||
if match_guard.player1 == player1_username.0 {
|
||||
player1.color = Color::Red;
|
||||
@@ -53,13 +58,16 @@ impl RoundRobin {
|
||||
player1.color = Color::Yellow;
|
||||
let _ = send(&player1.connection, "GAME:START:0");
|
||||
}
|
||||
|
||||
drop(player1);
|
||||
|
||||
let mut player2 = clients_guard.get(&player2_addr.0).unwrap().write().await;
|
||||
|
||||
player2.current_match = Some(match_id);
|
||||
player2.ready = false;
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!("READY:{}:{}", player2.username.clone(), false),
|
||||
)
|
||||
.await;
|
||||
|
||||
if match_guard.player1 == player2_addr.0 {
|
||||
player2.color = Color::Red;
|
||||
@@ -68,17 +76,24 @@ impl RoundRobin {
|
||||
player2.color = Color::Yellow;
|
||||
let _ = send(&player2.connection, "GAME:START:0");
|
||||
}
|
||||
|
||||
drop(player2);
|
||||
|
||||
matches.write().await.insert(match_id, new_match.clone());
|
||||
broadcast_message(
|
||||
&self.observers,
|
||||
&format!(
|
||||
"GAME:START:{},{},{}",
|
||||
match_id, match_guard.player1, match_guard.player2
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Tournament for RoundRobin {
|
||||
async fn new(ready_players: &[String], _: &Server) -> RoundRobin {
|
||||
async fn new(ready_players: &[String], server: &Server) -> RoundRobin {
|
||||
let mut result = RoundRobin {
|
||||
players: HashMap::new(),
|
||||
top_half: Vec::new(),
|
||||
@@ -86,6 +101,7 @@ impl Tournament for RoundRobin {
|
||||
completed: false,
|
||||
current_matches: Vec::new(),
|
||||
usernames: ready_players.to_vec(),
|
||||
observers: server.observers.clone(),
|
||||
};
|
||||
|
||||
let size = ready_players.len();
|
||||
|
||||
Reference in New Issue
Block a user