use std::{ sync::Arc, }; use futures::StreamExt; use tokio::sync::Mutex; use opengl_rust::{ network_protocol::*, quinn_common::make_server_endpoint, }; #[tokio::main] async fn main () -> anyhow::Result <()> { let server_addr = "127.0.0.1:5000".parse().unwrap(); let (mut incoming, server_cert) = make_server_endpoint(server_addr)?; let state = NetworkedState { positions: vec! [ (32.0, 32.0), ], }; let state = Arc::new (Mutex::new (state)); // let connected_players = Arc::new (Mutex::new (vec! [])); // accept a single connection let server_task = tokio::spawn (async move { use opengl_rust::timestep::TimeStep; let incoming_conn = incoming.next().await.unwrap(); let new_conn = incoming_conn.await.unwrap(); println!( "[server] connection accepted: addr={}", new_conn.connection.remote_address() ); let quinn::NewConnection { connection, mut datagrams, .. } = new_conn; let mut i = 0_u64; let cmd = Arc::new (Mutex::new (NetworkCommand::default ())); let cmd_2 = Arc::clone (&cmd); // Read player commands tokio::spawn (async move { while let Some (Ok (datagram)) = datagrams.next ().await { let cmd: NetworkCommand = rmp_serde::from_slice (&datagram)?; let mut guard = cmd_2.lock ().await; *guard = cmd; } Ok::<_, anyhow::Error> (()) }); let mut time_step = TimeStep::new (120, 1000); let mut state = NetworkedState { positions: vec! [ (32.0, 32.0), ], }; loop { let cmd = { let guard = cmd.lock ().await; guard.clone () }; let frames_to_do = time_step.step (); for _ in 0..frames_to_do { let speed = 0.25; if cmd.left { state.positions [0].0 -= speed; } if cmd.right { state.positions [0].0 += speed; } if cmd.up { state.positions [0].1 += speed; } if cmd.down { state.positions [0].1 -= speed; } } let bytes = rmp_serde::to_vec (&state)?; connection.send_datagram (bytes.into ())?; i += 1; tokio::time::sleep (std::time::Duration::from_millis(16)).await; } // Dropping all handles associated with a connection implicitly closes it Ok::<_, anyhow::Error> (()) }); tokio::fs::write ("quic_server.crt", &server_cert).await?; /* let endpoint = make_client_endpoint("0.0.0.0:0".parse().unwrap(), &[&server_cert])?; // connect to server let quinn::NewConnection { connection, mut uni_streams, .. } = endpoint .connect(&server_addr, "localhost") .unwrap() .await .unwrap(); println!("[client] connected: addr={}", connection.remote_address()); // Waiting for a stream will complete with an error when the server closes the connection let _ = uni_streams.next().await; // Give the server has a chance to clean up endpoint.wait_idle().await; */ server_task.await??; Ok(()) }