use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::sync::broadcast;
use serde_json;
use hyperchess::protocol::GameMessage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let listener = TcpListener::bind("0.0.0.0:8080").await?;
println!("Chess Server running on port 8080...");
println!("Waiting for players...");
let (tx, _rx) = broadcast::channel(100);
let mut player_count = 0;
loop {
let (mut socket, addr) = listener.accept().await?;
player_count += 1;
println!("Player {} connected: {}", player_count, addr);
let tx = tx.clone();
let mut rx = tx.subscribe();
let my_color = if player_count % 2 != 0 { "white" } else { "black" };
tokio::spawn(async move {
let (mut reader, mut writer) = socket.split();
let start_msg = GameMessage::GameStart(my_color.to_string());
let start_json = serde_json::to_string(&start_msg).unwrap();
let _ = writer.write_all(start_json.as_bytes()).await;
let mut buffer = [0; 1024];
loop {
tokio::select! {
result = reader.read(&mut buffer) => {
match result {
Ok(0) => break, Ok(n) => {
if let Ok(msg) = serde_json::from_slice::<GameMessage>(&buffer[..n]) {
match msg {
GameMessage::MakeMove { from, to } => {
println!("Move received from {}: {} -> {}", my_color, from, to);
let broadcast_msg = GameMessage::OpponentMove { from, to };
let _ = tx.send((broadcast_msg, my_color.to_string()));
}
_ => {}
}
}
}
Err(_) => break,
}
}
Ok((msg, sender_color)) = rx.recv() => {
if sender_color != my_color {
let json = serde_json::to_string(&msg).unwrap();
let _ = writer.write_all(json.as_bytes()).await;
}
}
}
}
println!("Player disconnected");
});
}
}