finished server main hopefully

This commit is contained in:
2026-05-14 18:53:48 -05:00
parent dc2fefdae2
commit 88b1cb8076

View File

@@ -1,3 +1,103 @@
fn main() {
println!("Hello, world!");
use std::collections::HashMap;
use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::RwLock; // Use Tokio's async-aware lock
// Type alias for our shared thread-safe state
type Db = Arc<RwLock<HashMap<String, String>>>;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Bind to all interfaces on port 5901
let listener = TcpListener::bind("0.0.0.0:5901").await?;
let db: Db = Arc::new(RwLock::new(HashMap::new()));
println!("🚀 Escape Room Server active on port 5901");
println!("Waiting for teams to connect...");
loop {
let (socket, _) = listener.accept().await?;
let db_clone = Arc::clone(&db);
// Spawn a new async task for every connection
tokio::spawn(async move {
if let Err(e) = handle_connection(socket, db_clone).await {
eprintln!("[SOCKET ERROR] {}", e);
}
});
}
}
async fn handle_connection(mut socket: TcpStream, db: Db) -> std::io::Result<()> {
let mut buf = [0; 1024];
let n = socket.read(&mut buf).await?;
// Connection closed
if n == 0 {
return Ok(());
}
let request = String::from_utf8_lossy(&buf[..n]);
let parts: Vec<&str> = request.trim().split_whitespace().collect();
if parts.is_empty() {
return Ok(());
}
match parts[0].to_uppercase().as_str() {
// Teams submit their solution: PUT [team_id] [value]
"PUT" => {
if parts.len() == 3 {
let team_id = parts[1].to_string();
let val = parts[2].to_string();
let mut data = db.write().await; // Async lock
data.insert(team_id.clone(), val.clone());
socket.write_all(b"ACK\n").await?;
println!("[LOG] Team {} submitted solution: {}", team_id, val);
}
}
// Teams request previous solution: GET [prev_team_id]
"GET" => {
if parts.len() == 2 {
let target_id = parts[1];
let data = db.read().await; // Async lock
let response = data
.get(target_id)
.cloned()
.unwrap_or_else(|| "-1".to_string());
if response == "-1" {
println!("[WAIT] Team requested {}, but no data yet.", target_id);
}
socket.write_all(response.as_bytes()).await?;
}
}
// Admin override: ADMIN SET [team_id] [value]
"ADMIN" => {
if parts.len() == 4 && parts[1].to_uppercase() == "SET" {
let team_id = parts[2].to_string();
let val = parts[3].to_string();
let mut data = db.write().await;
data.insert(team_id.clone(), val.clone());
socket.write_all(b"ADMIN_OK\n").await?;
println!("[ADMIN] Manual set: Team {} -> {}", team_id, val);
}
}
_ => {
socket.write_all(b"ERR_INVALID_CMD\n").await?;
}
}
Ok(())
}