From 3e15edc4c4b0cbd62e4521173a73de7640290469 Mon Sep 17 00:00:00 2001 From: Martin Indra Date: Tue, 22 Aug 2023 12:03:56 +0200 Subject: [PATCH] WIP --- crates/connector/tests/commands.rs | 10 ++ crates/connector/tests/network.rs | 108 +++++++++++++----- .../connection/{ => deliveries}/confirms.rs | 0 .../{deliveries.rs => deliveries/mod.rs} | 11 +- .../connection/{ => deliveries}/pending.rs | 3 +- .../connection/{ => deliveries}/received.rs | 0 crates/net/src/connection/mod.rs | 5 +- crates/net/src/tasks/usender.rs | 1 + docs/src/multiplayer/connector/protocol.md | 3 +- 9 files changed, 101 insertions(+), 40 deletions(-) rename crates/net/src/connection/{ => deliveries}/confirms.rs (100%) rename crates/net/src/connection/{deliveries.rs => deliveries/mod.rs} (97%) rename crates/net/src/connection/{ => deliveries}/pending.rs (93%) rename crates/net/src/connection/{ => deliveries}/received.rs (100%) diff --git a/crates/connector/tests/commands.rs b/crates/connector/tests/commands.rs index c58b7047..d26ce7ce 100644 --- a/crates/connector/tests/commands.rs +++ b/crates/connector/tests/commands.rs @@ -42,6 +42,10 @@ fn test() { comms_a.send(ToServer::OpenGame { max_players: 3 }).await; let mut response = comms_a.recv::().await; + + // TODO + println!("A"); + assert_eq!(response.len(), 1); let response = response.pop().unwrap(); let game_port = match response { @@ -55,10 +59,16 @@ fn test() { comms_d.port = game_port; check_response!(comms_a, FromGame::Joined(1)); + // TODO + println!("b"); comms_b.send(ToGame::Join).await; check_response!(comms_b, FromGame::Joined(2)); + // TODO + println!("c"); check_response!(comms_a, FromGame::PeerJoined(2)); + // TODO + println!("d"); comms_a.send(ToGame::Readiness(Readiness::Ready)).await; // The other player is not yet ready -> no message should be received. diff --git a/crates/connector/tests/network.rs b/crates/connector/tests/network.rs index 5c32aa98..c0b40a61 100644 --- a/crates/connector/tests/network.rs +++ b/crates/connector/tests/network.rs @@ -4,7 +4,7 @@ use std::{ }; use async_std::{prelude::FutureExt, task}; -use de_net::Socket; +use de_net::{Reliability, Socket}; use futures::join; use ntest::timeout; @@ -14,8 +14,6 @@ mod common; const SERVER_ADDR: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8082)); -// TODO fix headers - #[derive(Debug)] struct ReceivedBuffer(Vec); @@ -36,10 +34,14 @@ impl ReceivedBuffer { ); } - fn find_id(&self, filter_reliable: bool, filter_data: &[u8]) -> Option { + fn find_id(&self, filter_reliability: Reliability, filter_data: &[u8]) -> Option { self.0.iter().find_map(|incomming| match incomming { - Incomming::Data { reliable, id, data } => { - if *reliable == filter_reliable && data == filter_data { + Incomming::Data { + reliability, + id, + data, + } => { + if *reliability == filter_reliability && data == filter_data { Some(*id) } else { None @@ -70,7 +72,16 @@ impl ReceivedBuffer { self.0.push(Incomming::Confirm(id)); } } else { - let reliable = buf[0] & 64 > 0; + let reliability = (buf[0] & 96) >> 5; + let reliability = if reliability == 0 { + Reliability::Unreliable + } else if reliability == 1 { + Reliability::Unordered + } else if reliability == 2 { + Reliability::SemiOrdered + } else { + panic!("Invalid reliability bits"); + }; id_bytes[0] = 0; id_bytes[1] = buf[1]; @@ -79,7 +90,7 @@ impl ReceivedBuffer { let id = u32::from_be_bytes(id_bytes); self.0.push(Incomming::Data { - reliable, + reliability, id, data: buf[4..n].to_vec(), }); @@ -91,7 +102,7 @@ impl ReceivedBuffer { enum Incomming { Confirm(u32), Data { - reliable: bool, + reliability: Reliability, id: u32, data: Vec, }, @@ -112,17 +123,22 @@ fn test() { received.load(&mut client, &mut buffer).await; // [5, 2] -> FromGame::PeerJoined(1) - let id = received.find_id(true, &[5, 2]).unwrap().to_be_bytes(); + let id = received + .find_id(Reliability::SemiOrdered, &[5, 2]) + .unwrap() + .to_be_bytes(); // And send a confirmation client .send(server, &[128, 0, 0, 0, id[1], id[2], id[3]]) .await .unwrap(); - let first_id = received.find_id(true, &[5, 6, 7, 8]).unwrap(); + let first_id = received + .find_id(Reliability::Unordered, &[5, 6, 7, 8]) + .unwrap(); let mut data = [22; 412]; - data[0] = 64; // Reliable + data[0] = 32; // Unordered data[1] = 0; data[2] = 0; data[3] = 22; @@ -132,7 +148,9 @@ fn test() { received.load(&mut client, &mut buffer).await; received.load(&mut client, &mut buffer).await; received.assert_confirmed(22); - received.find_id(false, &[82, 83, 84]).unwrap(); + received + .find_id(Reliability::Unreliable, &[82, 83, 84]) + .unwrap(); // Try to send invalid data -- wrong header client @@ -148,10 +166,20 @@ fn test() { // Two retries before we confirm. let mut received = ReceivedBuffer::new(); received.load(&mut client, &mut buffer).await; - assert_eq!(received.find_id(true, &[5, 6, 7, 8]).unwrap(), first_id); + assert_eq!( + received + .find_id(Reliability::Unordered, &[5, 6, 7, 8]) + .unwrap(), + first_id + ); let mut received = ReceivedBuffer::new(); received.load(&mut client, &mut buffer).await; - assert_eq!(received.find_id(true, &[5, 6, 7, 8]).unwrap(), first_id); + assert_eq!( + received + .find_id(Reliability::Unordered, &[5, 6, 7, 8]) + .unwrap(), + first_id + ); let id = first_id.to_be_bytes(); // And send a confirmation @@ -160,8 +188,8 @@ fn test() { .await .unwrap(); - client.send(server, &[64, 0, 0, 92, 16]).await.unwrap(); - client.send(server, &[64, 0, 0, 86, 23]).await.unwrap(); + client.send(server, &[32, 0, 0, 92, 16]).await.unwrap(); + client.send(server, &[32, 0, 0, 86, 23]).await.unwrap(); let mut received = ReceivedBuffer::new(); received.load(&mut client, &mut buffer).await; received.assert_confirmed(92); @@ -181,8 +209,8 @@ fn test() { let mut buffer = [0u8; 1024]; client - // Reliable - .send(server, &[64, 0, 0, 14, 5, 6, 7, 8]) + // unordered + .send(server, &[32, 0, 0, 14, 5, 6, 7, 8]) .await .unwrap(); @@ -190,7 +218,10 @@ fn test() { received.load(&mut client, &mut buffer).await; received.load(&mut client, &mut buffer).await; received.assert_confirmed(14); - let id = received.find_id(true, &[22; 408]).unwrap().to_be_bytes(); + let id = received + .find_id(Reliability::Unordered, &[22; 408]) + .unwrap() + .to_be_bytes(); // Sending confirmation client @@ -209,7 +240,10 @@ fn test() { let mut received = ReceivedBuffer::new(); received.load(&mut client, &mut buffer).await; - let id = received.find_id(true, &[16]).unwrap().to_be_bytes(); + let id = received + .find_id(Reliability::Unordered, &[16]) + .unwrap() + .to_be_bytes(); client .send(server, &[128, 0, 0, 0, id[1], id[2], id[3]]) .await @@ -217,7 +251,10 @@ fn test() { let mut received = ReceivedBuffer::new(); received.load(&mut client, &mut buffer).await; - let id = received.find_id(true, &[23]).unwrap().to_be_bytes(); + let id = received + .find_id(Reliability::Unordered, &[23]) + .unwrap() + .to_be_bytes(); client .send(server, &[128, 0, 0, 0, id[1], id[2], id[3]]) .await @@ -247,11 +284,11 @@ async fn create_game() -> (Socket, u16) { let mut client = Socket::bind(None).await.unwrap(); - // [64 + 32] -> reliable + Peers::Server + // [64 + 16] -> semi-ordered + Peers::Server // [0, 0, 7] -> datagram ID = 7 // [1 3] -> ToGame::OpenGame { max_players: 3 } client - .send(SERVER_ADDR, &[64 + 32, 0, 0, 7, 1, 3]) + .send(SERVER_ADDR, &[64 + 16, 0, 0, 7, 1, 3]) .await .unwrap(); @@ -261,11 +298,16 @@ async fn create_game() -> (Socket, u16) { assert_eq!(received.0.len(), 1); let port = { - let Incomming::Data { reliable, id, data } = &(received.0)[0] else { + let Incomming::Data { + reliability, + id, + data, + } = &(received.0)[0] + else { panic!("Unexpected data received: {:?}", received); }; - assert!(reliable); + assert!(reliability.is_reliable()); // Confirm let id = id.to_be_bytes(); @@ -297,7 +339,10 @@ async fn create_game() -> (Socket, u16) { received.load(&mut client, &mut buffer).await; // [2, 1] -> FromGame::Joined(1) - let id = received.find_id(true, &[2, 1]).unwrap().to_be_bytes(); + let id = received + .find_id(Reliability::SemiOrdered, &[2, 1]) + .unwrap() + .to_be_bytes(); client .send(server, &[128, 0, 0, 0, id[1], id[2], id[3]]) .await @@ -312,10 +357,10 @@ async fn join_game(game_port: u16) -> Socket { let server = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, game_port)); let mut client = Socket::bind(None).await.unwrap(); - // [64 + 32] -> reliable + Peers::Server + // [64 + 16] -> semi-ordered + Peers::Server // [0, 0, 3] -> datagram ID = 3 // [1] -> ToGame::Join - client.send(server, &[64 + 32, 0, 0, 3, 1]).await.unwrap(); + client.send(server, &[64 + 16, 0, 0, 3, 1]).await.unwrap(); let mut received = ReceivedBuffer::new(); received.load(&mut client, &mut buffer).await; @@ -323,7 +368,10 @@ async fn join_game(game_port: u16) -> Socket { received.assert_confirmed(3); // [2, 2] -> FromGame::Joined(2) - let id = received.find_id(true, &[2, 2]).unwrap().to_be_bytes(); + let id = received + .find_id(Reliability::SemiOrdered, &[2, 2]) + .unwrap() + .to_be_bytes(); client .send(server, &[128, 0, 0, 0, id[1], id[2], id[3]]) .await diff --git a/crates/net/src/connection/confirms.rs b/crates/net/src/connection/deliveries/confirms.rs similarity index 100% rename from crates/net/src/connection/confirms.rs rename to crates/net/src/connection/deliveries/confirms.rs diff --git a/crates/net/src/connection/deliveries.rs b/crates/net/src/connection/deliveries/mod.rs similarity index 97% rename from crates/net/src/connection/deliveries.rs rename to crates/net/src/connection/deliveries/mod.rs index 7422cc58..c7bdb481 100644 --- a/crates/net/src/connection/deliveries.rs +++ b/crates/net/src/connection/deliveries/mod.rs @@ -4,15 +4,20 @@ use async_std::{ channel::{SendError, Sender}, sync::{Arc, Mutex, MutexGuard}, }; +pub(crate) use received::ReceivedIdError; -use super::{ - book::{Connection, ConnectionBook}, +use self::{ confirms::{ConfirmsBuffer, MAX_BUFF_AGE}, pending::Pending, - received::{IdContinuity, Received, ReceivedIdError}, + received::{IdContinuity, Received}, }; +use super::book::{Connection, ConnectionBook}; use crate::{header::PackageId, record::DeliveryRecord, tasks::OutDatagram, Reliability}; +mod confirms; +mod pending; +mod received; + // TODO rename #[derive(Clone)] pub(crate) struct Confirmations { diff --git a/crates/net/src/connection/pending.rs b/crates/net/src/connection/deliveries/pending.rs similarity index 93% rename from crates/net/src/connection/pending.rs rename to crates/net/src/connection/deliveries/pending.rs index 406078a2..57f320a7 100644 --- a/crates/net/src/connection/pending.rs +++ b/crates/net/src/connection/deliveries/pending.rs @@ -1,7 +1,6 @@ use std::collections::BTreeMap; -use super::databuf::DataBuf; -use crate::{header::PackageId, record::DeliveryRecord}; +use crate::{connection::databuf::DataBuf, header::PackageId, record::DeliveryRecord}; /// Buffer for packages delivered out-of-order and thus awaiting the right /// moment to be delivered. diff --git a/crates/net/src/connection/received.rs b/crates/net/src/connection/deliveries/received.rs similarity index 100% rename from crates/net/src/connection/received.rs rename to crates/net/src/connection/deliveries/received.rs diff --git a/crates/net/src/connection/mod.rs b/crates/net/src/connection/mod.rs index 3d0bb60d..283e2561 100644 --- a/crates/net/src/connection/mod.rs +++ b/crates/net/src/connection/mod.rs @@ -1,11 +1,8 @@ pub(crate) use deliveries::Confirmations; -pub(crate) use received::ReceivedIdError; +pub(crate) use deliveries::ReceivedIdError; pub(crate) use resend::Resends; mod book; -mod confirms; mod databuf; mod deliveries; -mod pending; -mod received; mod resend; diff --git a/crates/net/src/tasks/usender.rs b/crates/net/src/tasks/usender.rs index 4afa931e..e05d120f 100644 --- a/crates/net/src/tasks/usender.rs +++ b/crates/net/src/tasks/usender.rs @@ -20,6 +20,7 @@ pub(super) async fn run( ) { info!("Starting package sender on port {port}..."); + // TODO count each user independently let mut counter_reliable = PackageIdRange::counter(); let mut counter_unreliable = PackageIdRange::counter(); diff --git a/docs/src/multiplayer/connector/protocol.md b/docs/src/multiplayer/connector/protocol.md index 8bd8b974..d50dba32 100644 --- a/docs/src/multiplayer/connector/protocol.md +++ b/docs/src/multiplayer/connector/protocol.md @@ -24,7 +24,8 @@ by the mask `0b1000_0000`). Each user package has an ID, encoded within the last three bytes of the datagram header. These IDs increment until they reach the maximum value that can be encoded within three bytes, after which the counter resets to 0. The ID -sequence for reliable and unreliable packages are independent. +sequence for reliable and unreliable packages are independent. Each connection +has it own sequence. Packages can be transmitted in either reliable or non-reliable mode. Reliability is signaled by the second highest bit of the flags byte