From 2135bb0f241085a7b894b6e9624b0131bb8e20cb Mon Sep 17 00:00:00 2001 From: _ <> Date: Sat, 8 May 2021 23:34:52 +0000 Subject: [PATCH] :construction: --- Cargo.lock | 1 + Cargo.toml | 1 + src/bin/quic_server.rs | 179 +++++++++++++++++++++-------------------- 3 files changed, 92 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93efb5b..e9da0bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,6 +521,7 @@ version = "0.1.0" dependencies = [ "anyhow", "byteorder", + "bytes", "float-ord", "futures", "futures-util", diff --git a/Cargo.toml b/Cargo.toml index 5ac0ee7..30c6b6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" anyhow = "1.0.36" byteorder = "1.3.2" +bytes = "1.0.1" float-ord = "0.2.0" futures = "0.3.8" futures-util = "0.3.9" diff --git a/src/bin/quic_server.rs b/src/bin/quic_server.rs index aacd205..07c9538 100644 --- a/src/bin/quic_server.rs +++ b/src/bin/quic_server.rs @@ -10,116 +10,117 @@ use opengl_rust::{ quinn_common::make_server_endpoint, }; +struct ConnectedPlayer { + connection: quinn::Connection, + cmd: NetworkCommand, + position: (f32, f32), +} + #[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! [])); + let (mut incoming, server_cert) = make_server_endpoint (server_addr)?; + tokio::fs::write ("quic_server.crt", &server_cert).await?; - // 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 { + let connected_players = Arc::new (Mutex::new (vec! [])); + + use opengl_rust::timestep::TimeStep; + + let mut player_seq = 0; + 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 guard = connected_players.lock ().await; + guard.push (ConnectedPlayer { connection, - mut datagrams, - .. - } = new_conn; + cmd: NetworkCommand::default (), + position: (32.0, 32.0), + }); + } + + // Read player commands + { + let player_seq = player_seq; + let connected_players = Arc::clone (&connected_players); - 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; + let mut guard = connected_players.lock ().await; + guard [player_seq].cmd = cmd; } Ok::<_, anyhow::Error> (()) }); + } + + player_seq += 1; + + let mut time_step = TimeStep::new (120, 1000); + let mut state = NetworkedState { + positions: vec! [ + (32.0, 32.0), + ], + }; + + let mut i = 0_u64; + + loop { + let frames_to_do = time_step.step (); - 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 (); + let state; + { + let mut guard = connected_players.lock ().await; 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; + + for player in &mut guard [..] { + let cmd = &player.cmd; + let mut pos = &mut player.position; + + if cmd.left { + pos.0 -= speed; + } + if cmd.right { + pos.0 += speed; + } + if cmd.up { + pos.1 += speed; + } + if cmd.down { + pos.1 -= speed; + } } } - let bytes = rmp_serde::to_vec (&state)?; - connection.send_datagram (bytes.into ())?; + state = NetworkedState { + positions: guard.iter () + .map (|player| player.position) + .collect (), + }; + + let bytes = bytes::Bytes::from (rmp_serde::to_vec (&state)?); + + for player in &guard [..] { + player.connection.send_datagram (bytes.clone ())?; + } 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??; + } + + tokio::time::sleep (std::time::Duration::from_millis(16)).await; + } Ok(()) }