2021-32-bit-holiday-jam/src/bin/quic_server.rs

135 lines
2.7 KiB
Rust

use std::{
sync::Arc,
};
use futures::StreamExt;
use tokio::sync::Mutex;
use opengl_rust::{
network_protocol::*,
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)?;
tokio::fs::write ("quic_server.crt", &server_cert).await?;
let connected_players = Arc::new (Mutex::new (vec! []));
{
let connected_players = Arc::clone (&connected_players);
tokio::spawn (async move {
let mut player_seq = 0;
while let Some (incoming_conn) = incoming.next ().await {
let new_conn = incoming_conn.await?;
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,
cmd: NetworkCommand::default (),
position: (32.0, 32.0),
});
}
// Read player commands
{
let player_seq = player_seq;
let connected_players = Arc::clone (&connected_players);
tokio::spawn (async move {
while let Some (Ok (datagram)) = datagrams.next ().await {
let cmd: NetworkCommand = rmp_serde::from_slice (&datagram)?;
let mut guard = connected_players.lock ().await;
guard [player_seq].cmd = cmd;
}
Ok::<_, anyhow::Error> (())
});
}
player_seq += 1;
}
Ok::<_, anyhow::Error> (())
});
}
let mut time_step = opengl_rust::timestep::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 state;
{
let mut guard = connected_players.lock ().await;
for _ in 0..frames_to_do {
let speed = 0.25;
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;
}
}
}
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;
}
Ok(())
}