From b5c340c10418c5c7bac925a474ff72c8f64c89bb Mon Sep 17 00:00:00 2001 From: Aubrey Taylor Date: Sat, 21 Dec 2024 05:35:44 -0600 Subject: [PATCH] mvp proximity chat --- Cargo.lock | 253 -------------------------------------------- Cargo.toml | 3 - examples/extract.rs | 22 ++-- flake.lock | 16 +++ flake.nix | 37 ++++--- src/faker.rs | 20 +++- src/server/mod.rs | 27 +++-- src/server/prox.rs | 138 ++++++++++++++++++------ todo.txt | 10 +- 9 files changed, 194 insertions(+), 332 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 776fc2b..403d8e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,12 +26,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "almost" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa2999eb46af81abb65c2d30d446778d7e613b60bbf4e174a027e80f90a3c14" - [[package]] name = "anstream" version = "0.6.18" @@ -90,12 +84,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "array-init" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" - [[package]] name = "asn1-rs" version = "0.6.2" @@ -162,30 +150,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "binrw" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d4bca59c20d6f40c2cc0802afbe1e788b89096f61bdf7aeea6bf00f10c2909b" -dependencies = [ - "array-init", - "binrw_derive", - "bytemuck", -] - -[[package]] -name = "binrw_derive" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8ba42866ce5bced2645bfa15e97eef2c62d2bdb530510538de8dd3d04efff3c" -dependencies = [ - "either", - "owo-colors", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "bitflags" version = "2.6.0" @@ -207,12 +171,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "bytemuck" -version = "1.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" - [[package]] name = "byteorder" version = "1.5.0" @@ -295,16 +253,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "colorchoice" version = "1.0.3" @@ -355,65 +303,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cxx" -version = "1.0.135" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d44ff199ff93242c3afe480ab588d544dd08d72e92885e152ffebc670f076ad" -dependencies = [ - "cc", - "cxxbridge-cmd", - "cxxbridge-flags", - "cxxbridge-macro", - "foldhash", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.135" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fd8f17ad454fc1e4f4ab83abffcc88a532e90350d3ffddcb73030220fcbd52" -dependencies = [ - "cc", - "codespan-reporting", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.90", -] - -[[package]] -name = "cxxbridge-cmd" -version = "1.0.135" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4717c9c806a9e07fdcb34c84965a414ea40fafe57667187052cf1eb7f5e8a8a9" -dependencies = [ - "clap", - "codespan-reporting", - "proc-macro2", - "quote", - "syn 2.0.90", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.135" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f6515329bf3d98f4073101c7866ff2bec4e635a13acb82e3f3753fff0bf43cb" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.135" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb93e6a7ce8ec985c02bbb758237a31598b340acbbc3c19c5a4fa6adaaac92ab" -dependencies = [ - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.90", -] - [[package]] name = "data-encoding" version = "2.6.0" @@ -464,12 +353,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - [[package]] name = "equivalent" version = "1.0.1" @@ -482,12 +365,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "foldhash" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -754,12 +631,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" -[[package]] -name = "join_str" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de046f45ca45d4526a5d340223c0e03cef1f06457bee78a523d5ce55894ac0a" - [[package]] name = "js-sys" version = "0.3.76" @@ -782,15 +653,6 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "link-cplusplus" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" -dependencies = [ - "cc", -] - [[package]] name = "litemap" version = "0.7.4" @@ -959,12 +821,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" - [[package]] name = "pem" version = "3.0.4" @@ -1190,28 +1046,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "roead" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caa4e7e992638f39b4ecbde6f11e02dfbcf81dae42954ee5fba32111dd9e39ce" -dependencies = [ - "almost", - "binrw", - "cxx", - "cxx-build", - "indexmap", - "join_str", - "num-integer", - "num-traits", - "rustc-hash", - "rustc_version", - "serde", - "serde_json", - "smartstring", - "thiserror 1.0.69", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1224,15 +1058,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - [[package]] name = "rusticata-macros" version = "4.1.0" @@ -1297,18 +1122,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "rustversion" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - [[package]] name = "schannel" version = "0.1.27" @@ -1318,12 +1131,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "scratch" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" - [[package]] name = "security-framework" version = "3.1.0" @@ -1347,12 +1154,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" - [[package]] name = "serde" version = "1.0.216" @@ -1373,18 +1174,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "serde_json" -version = "1.0.133" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - [[package]] name = "sha2" version = "0.10.8" @@ -1426,17 +1215,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "smartstring" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" -dependencies = [ - "autocfg", - "static_assertions", - "version_check", -] - [[package]] name = "smo-server" version = "0.1.0" @@ -1447,7 +1225,6 @@ dependencies = [ "glam", "heapless", "newtype-enum", - "roead", "tokio", "tracing", "tracing-subscriber", @@ -1479,12 +1256,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.11.1" @@ -1530,15 +1301,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -1762,12 +1524,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - [[package]] name = "untrusted" version = "0.9.0" @@ -1910,15 +1666,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index c9700cc..4b94f1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,3 @@ uuid = { version = "1.11.0", features = ["v4"] } wtransport = "0.5.0" xtra = { version = "0.6.0", features = ["macros", "tokio"] } zerocopy = { version = "0.8.13", features = ["derive"] } - -[dev-dependencies] -roead = "1.0.0" diff --git a/examples/extract.rs b/examples/extract.rs index 91adae8..29f9494 100644 --- a/examples/extract.rs +++ b/examples/extract.rs @@ -1,13 +1,13 @@ fn main() { - let stages = std::fs::read_dir("game/stages").unwrap(); - for stage in stages { - let stage = stage.unwrap(); - let bytes: Vec = std::fs::read(stage.path()).unwrap(); - let data = roead::byml::Byml::from_binary(bytes).unwrap(); - let map = data.into_map().unwrap(); - let mtx: Vec = - map.get("ProjMatrix").unwrap().as_array().unwrap().into_iter().map(|a| a.as_float().unwrap()).collect(); - let mat4 = glam::Mat4::from_cols_slice(&mtx); - println!("{:?}", mat4); - } + // let stages = std::fs::read_dir("game/stages").unwrap(); + // for stage in stages { + // let stage = stage.unwrap(); + // let bytes: Vec = std::fs::read(stage.path()).unwrap(); + // let data = roead::byml::Byml::from_binary(bytes).unwrap(); + // let map = data.into_map().unwrap(); + // let mtx: Vec = + // map.get("ProjMatrix").unwrap().as_array().unwrap().into_iter().map(|a| a.as_float().unwrap()).collect(); + // let mat4 = glam::Mat4::from_cols_slice(&mtx); + // println!("{:?}", mat4); + // } } diff --git a/flake.lock b/flake.lock index f0cbe6d..244db60 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,20 @@ { "nodes": { + "crane": { + "locked": { + "lastModified": 1734744351, + "narHash": "sha256-fN9npuZHHHzDVr1wuKoh/TheHkerDaLB9l4vj/48Exg=", + "owner": "ipetkov", + "repo": "crane", + "rev": "a83a48a62640517588c3d137c948ed034706363c", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "fenix": { "inputs": { "nixpkgs": [ @@ -57,6 +72,7 @@ }, "root": { "inputs": { + "crane": "crane", "fenix": "fenix", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs" diff --git a/flake.nix b/flake.nix index bd18b28..493e4ee 100644 --- a/flake.nix +++ b/flake.nix @@ -6,12 +6,16 @@ url = "github:nix-community/fenix"; inputs.nixpkgs.follows = "nixpkgs"; }; + crane = { + url = "github:ipetkov/crane"; + }; }; outputs = { self, nixpkgs, flake-utils, fenix, + crane }: flake-utils.lib.eachDefaultSystem ( @@ -20,6 +24,19 @@ pkgs = import nixpkgs { inherit system overlays; }; + craneLib = crane.mkLib pkgs; + commonArgs = { + src = craneLib.cleanCargoSource ./.; + strictDeps = true; + + nativeBuildInputs = with pkgs; [pkg-config cmake]; + buildInputs = with pkgs; [ + openssl + zlib-ng + ] ++ lib.optionals stdenv.isDarwin [ + libiconv + ]; + }; in with pkgs; { devShells.default = mkShell { @@ -30,23 +47,9 @@ ]; }; formatter = pkgs.alejandra; - packages.default = rustPlatform.buildRustPackage { - name = "smo-server"; - src = ./.; - nativeBuildInputs = [pkg-config cmake]; - buildInputs = [openssl]; - cargoDeps = rustPlatform.importCargoLock { - lockFile = ./Cargo.lock; - outputHashes = { - "newtype-enum-0.1.0" = "sha256-DBFSgtuwn51U3nvSxa0SQZKEHniC4UFVBHIeQjkXAvw="; - }; - }; - }; - # nixosModules.default = { config }: with pkgs.lib { - # options.services.smo-server = { - # enable = mkEnableOption "" - # }; - # } + packages.default = craneLib.buildPackage (commonArgs // { + cargoArtifacts = craneLib.buildDepsOnly commonArgs; + }); } ); } diff --git a/src/faker.rs b/src/faker.rs index e0d6e22..65f5dd9 100644 --- a/src/faker.rs +++ b/src/faker.rs @@ -2,10 +2,14 @@ use glam::Vec3; use xtra::{Actor, Address, Handler}; use crate::{ + manager, packet::{ Packet, PacketData, PacketData_variants::{Connect, Player}, - }, player::broadcast_packet, protocol::String + }, + player::broadcast_packet, + protocol::String, + server::PlayerConnected, }; pub struct Faker { @@ -15,6 +19,18 @@ pub struct Faker { impl Actor for Faker { type Stop = (); + async fn started(&mut self, _: &xtra::Mailbox) -> Result<(), Self::Stop> { + manager() + .send(PlayerConnected { + id: 1, + name: "Bot".try_into().unwrap(), + }) + .await + .unwrap(); + + Ok(()) + } + async fn stopped(self) -> Self::Stop {} } @@ -41,7 +57,7 @@ impl Handler for Faker { user_id: 1, udp: message.udp, data: PacketData::Player(Player { - position: (pos + Vec3::new(0., -150., 0.)).into(), + position: (pos * Vec3::new(1.0, 1.0, -1.0) + Vec3::new(0., -150., 0.)).into(), ..player }), }) diff --git a/src/server/mod.rs b/src/server/mod.rs index 76f6874..86da247 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -22,17 +22,15 @@ fn listeners() -> &'static RwLock>> &LISTENERS } -pub async fn web_main( - port: u16, - cert: PathBuf, - key: PathBuf, -) -> Address { +pub async fn web_main(port: u16, cert: PathBuf, key: PathBuf) -> Address { let span = info_span!("prox"); info!(parent: &span, "reading pems from {{ cert: {cert:?}, key: {key:?} }}"); let identity = Identity::load_pemfiles(cert, key).await.expect("failed to create identity from proximity pems"); let config = ServerConfig::builder().with_bind_default(port).with_identity(identity).build(); let endpoint = Endpoint::server(config).expect("failed to build proximity endpoint"); + info!("listening on webtransport port {port}"); + let manager = xtra::spawn_tokio( Manager { players: HashMap::new(), @@ -45,7 +43,7 @@ pub async fn web_main( async move { loop { let connection = endpoint.accept().await; - + ProximityPlayer::spawn(connection, manager.clone()); } } @@ -101,10 +99,11 @@ impl Handler for Manager { async fn handle(&mut self, message: PlayerConnected, _: &mut xtra::Context) -> Self::Return { let id = { - let id = self.next_id; - self.next_id += 1; - id - }; + let id = self.next_id; + self.next_id += 1; + id + }; + self.players.insert( message.id, PlayerInstance { @@ -114,7 +113,13 @@ impl Handler for Manager { stage: String::new_zeroed(), }, ); - self.broadcast(PlayerConnected { id: id as u128, name: message.name}).await; + + self + .broadcast(PlayerConnected { + id: id as u128, + name: message.name, + }) + .await; } } diff --git a/src/server/prox.rs b/src/server/prox.rs index 464bc8f..79d24ea 100644 --- a/src/server/prox.rs +++ b/src/server/prox.rs @@ -10,12 +10,15 @@ use wtransport::endpoint::IncomingSession; use xtra::{Actor, Address, Handler, Mailbox}; use zerocopy::{FromZeros, IntoBytes}; +use crate::{packet::CLIENT_NAME_SIZE, protocol::String}; + use super::{ listeners, ChangedStage, Manager, PlayerConnected, PlayerDisconnected, PlayerMoved, RequestState, UuidString, }; pub struct ProximityPlayer { id: UuidString, + name: String, send: wtransport::SendStream, connection: Arc, } @@ -30,11 +33,14 @@ impl ProximityPlayer { ); let (mut send, mut recv) = connection.accept_bi().await.expect("failed to start channel"); - trace!("getting peerjs uuid"); + trace!("getting uuid and name"); let mut id = UuidString::new_zeroed(); recv.read_exact(id.as_mut_bytes()).await.expect("failed to read uuid"); + let mut name = String::new_zeroed(); + recv.read_exact(name.as_mut_bytes()).await.expect("failed to read name"); let span = info_span!("", %id); span.in_scope(|| trace!("uuid parsed")); + info!(parent: &span, "connected as {name}"); let state = manager.send(RequestState).await.unwrap(); @@ -47,8 +53,11 @@ impl ProximityPlayer { { let listeners = listeners().read().await; send.write_u32_le(listeners.len() as u32).await.expect("failed to write peer length"); - for (id, _) in listeners.iter() { - send.write_all(id.as_bytes()).await.expect("failed to write peer id") + for (id, listener) in listeners.iter() { + if let Ok(name) = listener.send(GetName).await { + send.write_all(id.as_bytes()).await.expect("failed to write peer id"); + send.write_all(name.as_bytes()).await.expect("failed to write peer name"); + } } } @@ -82,7 +91,17 @@ impl ProximityPlayer { } .instrument(span.clone()), ); - xtra::run(mailbox, ProximityPlayer { id, send, connection }).instrument(span).await; + xtra::run( + mailbox, + ProximityPlayer { + id, + name, + send, + connection, + }, + ) + .instrument(span) + .await; } .in_current_span(), ); @@ -93,16 +112,38 @@ impl Actor for ProximityPlayer { type Stop = (); async fn started(&mut self, _: &Mailbox) -> Result<(), Self::Stop> { - for listener in listeners().write().await.iter() { - if *listener.0 != self.id { - let _ = listener - .1 + let changed_event = packet::Packet { + kind: packet::Kind::PeerConnectionChanged, + data: packet::PeerConnectionChanged { + id: FromZeros::new_zeroed(), + connected: true, + name: FromZeros::new_zeroed(), + }, + }; + + for (id, listener) in listeners().write().await.iter() { + if *id != self.id { + if let Ok(Ok(name)) = listener .send(PeerConnectionChanged { id: self.id, connected: true, + name: self.name, }) - .detach() - .await; + .await + { + let personalized = packet::Packet { + data: packet::PeerConnectionChanged { + id: *id, + name, + ..changed_event.data + }, + ..changed_event + }; + if let Err(error) = self.send.write_all(personalized.as_bytes()).await { + error!("error while sending peer info {error}"); + return Err(()); + } + } } } Ok(()) @@ -116,6 +157,7 @@ impl Actor for ProximityPlayer { .send(PeerConnectionChanged { id: self.id, connected: false, + name: self.name, }) .detach() .await; @@ -134,6 +176,15 @@ impl Handler for ProximityPlayer { } } +struct GetName; +impl Handler for ProximityPlayer { + type Return = String; + + async fn handle(&mut self, _: GetName, _: &mut xtra::Context) -> Self::Return { + self.name + } +} + impl Handler for ProximityPlayer { type Return = (); @@ -181,6 +232,9 @@ impl Handler for ProximityPlayer { ) .await; } + Event::TargetChanged(changed) => { + self.name = changed.name; + } } } } @@ -188,33 +242,43 @@ impl Handler for ProximityPlayer { impl Handler for ProximityPlayer { type Return = (); - async fn handle(&mut self, message: Offer, _: &mut xtra::Context) -> Self::Return { - Event::Offer(message).serialize(&mut self.send).await.expect("failed to write offer!"); + async fn handle(&mut self, message: Offer, ctx: &mut xtra::Context) -> Self::Return { + if let Err(error) = Event::Offer(message).serialize(&mut self.send).await { + error!("error while sending offer {error}"); + ctx.stop_self(); + } } } impl Handler for ProximityPlayer { type Return = (); - async fn handle(&mut self, message: Answer, _: &mut xtra::Context) -> Self::Return { - Event::Answer(message).serialize(&mut self.send).await.expect("failed to write offer!"); + async fn handle(&mut self, message: Answer, ctx: &mut xtra::Context) -> Self::Return { + if let Err(error) = Event::Answer(message).serialize(&mut self.send).await { + error!("error while sending player move {error}"); + ctx.stop_self(); + } } } impl Handler for ProximityPlayer { type Return = (); - async fn handle(&mut self, message: Candidate, _: &mut xtra::Context) -> Self::Return { - Event::Candidate(message).serialize(&mut self.send).await.expect("failed to write offer!"); + async fn handle(&mut self, message: Candidate, ctx: &mut xtra::Context) -> Self::Return { + if let Err(error) = Event::Candidate(message).serialize(&mut self.send).await { + error!("error while sending candidate {error}"); + ctx.stop_self(); + } } } struct PeerConnectionChanged { id: UuidString, connected: bool, + name: String, } impl Handler for ProximityPlayer { - type Return = (); + type Return = Result, ()>; async fn handle(&mut self, message: PeerConnectionChanged, ctx: &mut xtra::Context) -> Self::Return { let event = packet::Packet { @@ -222,15 +286,20 @@ impl Handler for ProximityPlayer { data: packet::PeerConnectionChanged { id: message.id, connected: message.connected, + name: message.name, }, }; if let Err(error) = self.send.write_all(event.as_bytes()).await { error!("error while sending player move {error}"); ctx.stop_self(); + return Err(()); } + + Ok(self.name) } } + impl Handler for ProximityPlayer { type Return = (); @@ -315,11 +384,12 @@ pub mod packet { use tracing::info; use wtransport::{RecvStream, SendStream}; use zerocopy::{FromZeros, Immutable, IntoBytes}; - use Event_variants::{Answer, Candidate, Offer}; + use Event_variants::{Answer, Candidate, Offer, TargetChanged}; use crate::{ packet::{CLIENT_NAME_SIZE, STAGE_GAME_NAME_SIZE}, protocol::String, + server::UuidString, }; pub const HYP_UUID_SIZE: usize = 36; @@ -331,7 +401,7 @@ pub mod packet { pub data: T, } - #[derive(IntoBytes, Immutable)] + #[derive(Clone, Copy, IntoBytes, Immutable)] #[repr(u8)] pub enum Kind { Connected = 0, @@ -371,28 +441,32 @@ pub mod packet { pub stage_name: String, } - #[derive(IntoBytes, Immutable)] + #[derive(Clone, Copy, IntoBytes, Immutable)] #[repr(C, packed)] pub struct PeerConnectionChanged { - pub id: String, + pub id: UuidString, pub connected: bool, + pub name: String, } #[newtype_enum] #[derive(Debug)] pub enum Event { Offer { - pub id: String, + pub id: UuidString, pub sdp: StdString, }, Answer { - pub id: String, + pub id: UuidString, pub sdp: StdString, }, Candidate { - pub id: String, + pub id: UuidString, pub candidate: StdString, }, + TargetChanged { + pub name: String, + }, } impl Event { @@ -407,21 +481,22 @@ pub mod packet { info!("writing event: {self:?}"); match self { - Event::Offer(offer) => { + Self::Offer(offer) => { send.write_u8(Kind::Offer as u8).await?; send.write_all(offer.id.as_bytes()).await?; write_string(send, offer.sdp).await?; } - Event::Answer(answer) => { + Self::Answer(answer) => { send.write_u8(Kind::Answer as u8).await?; send.write_all(answer.id.as_bytes()).await?; write_string(send, answer.sdp).await?; } - Event::Candidate(candidate) => { + Self::Candidate(candidate) => { send.write_u8(Kind::Candidate as u8).await?; send.write_all(candidate.id.as_bytes()).await?; write_string(send, candidate.candidate).await?; } + Self::TargetChanged(_) => unimplemented!(), } Ok(()) } @@ -444,18 +519,21 @@ pub mod packet { let kind = recv.read_u8().await?; info!("reading kind: {kind}"); let event = match kind { - 0 => Event::Offer(Offer { + 0 => Self::Offer(Offer { id: read_fixed_string(recv).await?, sdp: read_string(recv).await?, }), - 1 => Event::Answer(Answer { + 1 => Self::Answer(Answer { id: read_fixed_string(recv).await?, sdp: read_string(recv).await?, }), - 2 => Event::Candidate(Candidate { + 2 => Self::Candidate(Candidate { id: read_fixed_string(recv).await?, candidate: read_string(recv).await?, }), + 3 => Self::TargetChanged(TargetChanged { + name: read_fixed_string(recv).await?, + }), kind => bail!("invalid kind: {kind}"), }; diff --git a/todo.txt b/todo.txt index a9e766d..38e0247 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,5 @@ -players -> manager (accumulate player state) -manager -> proximity player (relay state changes) -proximity player -> web (relay state changes, signaling) -web -> proximity player (signaling) - +remove (de)serialization logs +muting, global chat +setup nginx +setup systemd unit for this server +static site generate and host prox chat website