fix: more disconnect stability fixes

This commit is contained in:
2026-04-23 19:54:45 -04:00
Unverified
parent 8a5d784f26
commit ba3ada8140
2 changed files with 41 additions and 46 deletions

View File

@@ -312,16 +312,22 @@ async fn handle_connection(
client.ready = false; client.ready = false;
if client.current_match.is_some() { if client.current_match.is_some() {
let current_match = sd.matches.read().await.get(&client.current_match.unwrap()).cloned().unwrap(); let current_match =
sd.matches.read().await.get(&client.current_match.unwrap()).cloned().unwrap();
let current_match = current_match.read().await; let current_match = current_match.read().await;
if current_match.timeout_thread.is_some() { if let Some(wait_thread) = &current_match.wait_thread {
current_match.timeout_thread.as_ref().unwrap().abort(); wait_thread.abort();
}
if let Some(timeout_thread) = &current_match.timeout_thread {
timeout_thread.abort();
} }
if current_match.demo_mode { if current_match.demo_mode {
sd.matches.write().await.remove(&current_match.id); sd.matches.write().await.remove(&current_match.id);
sd.broadcast(&format!("GAME:{}:TERMINATED", current_match.id)).await; sd.broadcast(&format!("GAME:{}:TERMINATED", current_match.id)).await;
sd.clients.write().await.remove(&username); sd.clients.write().await.remove(&username);
sd.broadcast(&format!("DISCONNECT:{}", username)).await;
} else { } else {
sd.disconnected_clients.write().await.push(username.clone()); sd.disconnected_clients.write().await.push(username.clone());
} }
@@ -331,13 +337,13 @@ async fn handle_connection(
sd.disconnected_clients.write().await.push(username.clone()); sd.disconnected_clients.write().await.push(username.clone());
} else { } else {
sd.clients.write().await.remove(&username); sd.clients.write().await.remove(&username);
sd.broadcast(&format!("DISCONNECT:{}", username)).await;
} }
} else { } else {
sd.clients.write().await.remove(&username); sd.clients.write().await.remove(&username);
}
sd.broadcast(&format!("DISCONNECT:{}", username)).await; sd.broadcast(&format!("DISCONNECT:{}", username)).await;
} }
}
sd.usernames.write().await.remove(&addr); sd.usernames.write().await.remove(&addr);
sd.observers.write().await.remove(&addr); sd.observers.write().await.remove(&addr);

View File

@@ -101,42 +101,24 @@ impl Server {
let mut client = client_guard.write().await; let mut client = client_guard.write().await;
client.addr = addr; client.addr = addr;
client.connection = tx.clone(); client.connection = tx.clone();
// I don't think this will fail
let match_id = client.current_match.unwrap();
let client_color = client.color;
drop(client); if let Some(current_match_id) = client.current_match {
let current_match = self.matches.read().await.get(&current_match_id).cloned().unwrap();
let matches_guard = self.matches.read().await; let mut current_match = current_match.write().await;
let mut the_match = matches_guard.get(&match_id).unwrap().write().await; current_match.ledger.clear();
if the_match.demo_mode { current_match.board = vec![vec![Color::None; 6]; 7];
drop(the_match); let opponent_username = if current_match.player1 == requested_username {
drop(matches_guard); current_match.player2.clone()
self.terminate_match(match_id).await;
return Ok(());
} else { } else {
the_match.ledger.clear(); current_match.player1.clone()
the_match.board = vec![vec![Color::None; 6]; 7];
let opponent_username = if the_match.player1 == requested_username {
the_match.player2.clone()
} else {
the_match.player1.clone()
}; };
if the_match.wait_thread.is_some() {
the_match.wait_thread.as_ref().unwrap().abort();
}
if the_match.timeout_thread.is_some() {
the_match.timeout_thread.as_ref().unwrap().abort();
}
let clients_guard = self.clients.read().await; let clients_guard = self.clients.read().await;
let opponent = clients_guard.get(&opponent_username).unwrap().read().await; let opponent = clients_guard.get(&opponent_username).unwrap().read().await;
let _ = send(&opponent.connection, "GAME:TERMINATED"); let _ = send(&opponent.connection, "GAME:TERMINATED");
let _ = send( let _ = send(
&tx, &tx,
&format!("GAME:START:{}", bool::from(client_color) as u8), &format!("GAME:START:{}", bool::from(client.color) as u8),
); );
let _ = send( let _ = send(
&opponent.connection, &opponent.connection,
@@ -166,6 +148,7 @@ impl Server {
if let Some(client_guard) = found_client { if let Some(client_guard) = found_client {
self.disconnected_clients.write().await.retain(|name| name != &requested_username); self.disconnected_clients.write().await.retain(|name| name != &requested_username);
self.usernames.write().await.insert(addr, requested_username.clone());
let mut client = client_guard.write().await; let mut client = client_guard.write().await;
client.addr = addr; client.addr = addr;
client.connection = tx.clone(); client.connection = tx.clone();
@@ -195,7 +178,6 @@ impl Server {
let _ = send(&tx, "RECONNECT:ACK"); let _ = send(&tx, "RECONNECT:ACK");
} }
} }
} else { } else {
return Err(anyhow::anyhow!(format!( return Err(anyhow::anyhow!(format!(
"ERROR:INVALID:RECONNECT:{}", "ERROR:INVALID:RECONNECT:{}",
@@ -1397,19 +1379,26 @@ impl Server {
self.broadcast(&format!("GAME:{}:TERMINATED", the_match.id)).await; self.broadcast(&format!("GAME:{}:TERMINATED", the_match.id)).await;
let clients_guard = self.clients.read().await; let clients_guard = self.clients.read().await;
if the_match.player1 != SERVER_PLAYER_USERNAME.to_string() { if the_match.player1 != SERVER_PLAYER_USERNAME.to_string() {
let mut player1 = clients_guard.get(&the_match.player1).unwrap().write().await; let player1 = clients_guard.get(&the_match.player1).cloned();
if let Some(player1) = player1 {
let mut player1 = player1.write().await;
let _ = send(&player1.connection, "GAME:TERMINATED"); let _ = send(&player1.connection, "GAME:TERMINATED");
player1.current_match = None; player1.current_match = None;
player1.color = Color::None; player1.color = Color::None;
} }
}
if the_match.player2 != SERVER_PLAYER_USERNAME.to_string() { if the_match.player2 != SERVER_PLAYER_USERNAME.to_string() {
let mut player2 = clients_guard.get(&the_match.player2).unwrap().write().await; let player2 = clients_guard.get(&the_match.player2).cloned();
if let Some(player2) = player2 {
let mut player2 = player2.write().await;
let _ = send(&player2.connection, "GAME:TERMINATED"); let _ = send(&player2.connection, "GAME:TERMINATED");
player2.current_match = None; player2.current_match = None;
player2.color = Color::None; player2.color = Color::None;
} }
}
drop(clients_guard); drop(clients_guard);
drop(the_match); drop(the_match);