mvp proximity chat

This commit is contained in:
Aubrey 2024-12-21 05:35:44 -06:00
parent 63d5b177b4
commit b5c340c104
No known key found for this signature in database
9 changed files with 194 additions and 332 deletions

253
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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<u8> = std::fs::read(stage.path()).unwrap();
let data = roead::byml::Byml::from_binary(bytes).unwrap();
let map = data.into_map().unwrap();
let mtx: Vec<f32> =
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<u8> = std::fs::read(stage.path()).unwrap();
// let data = roead::byml::Byml::from_binary(bytes).unwrap();
// let map = data.into_map().unwrap();
// let mtx: Vec<f32> =
// 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);
// }
}

View file

@ -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"

View file

@ -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;
});
}
);
}

View file

@ -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<Self>) -> 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<Packet> 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
}),
})

View file

@ -22,17 +22,15 @@ fn listeners() -> &'static RwLock<HashMap<UuidString, Address<ProximityPlayer>>>
&LISTENERS
}
pub async fn web_main(
port: u16,
cert: PathBuf,
key: PathBuf,
) -> Address<Manager> {
pub async fn web_main(port: u16, cert: PathBuf, key: PathBuf) -> Address<Manager> {
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(),
@ -101,10 +99,11 @@ impl Handler<PlayerConnected> for Manager {
async fn handle(&mut self, message: PlayerConnected, _: &mut xtra::Context<Self>) -> 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<PlayerConnected> 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;
}
}

View file

@ -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<CLIENT_NAME_SIZE>,
send: wtransport::SendStream,
connection: Arc<wtransport::Connection>,
}
@ -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<Self>) -> 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<Stop> for ProximityPlayer {
}
}
struct GetName;
impl Handler<GetName> for ProximityPlayer {
type Return = String<CLIENT_NAME_SIZE>;
async fn handle(&mut self, _: GetName, _: &mut xtra::Context<Self>) -> Self::Return {
self.name
}
}
impl Handler<Event> for ProximityPlayer {
type Return = ();
@ -181,6 +232,9 @@ impl Handler<Event> for ProximityPlayer {
)
.await;
}
Event::TargetChanged(changed) => {
self.name = changed.name;
}
}
}
}
@ -188,33 +242,43 @@ impl Handler<Event> for ProximityPlayer {
impl Handler<Offer> for ProximityPlayer {
type Return = ();
async fn handle(&mut self, message: Offer, _: &mut xtra::Context<Self>) -> 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>) -> 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<Answer> for ProximityPlayer {
type Return = ();
async fn handle(&mut self, message: Answer, _: &mut xtra::Context<Self>) -> 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>) -> 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<Candidate> for ProximityPlayer {
type Return = ();
async fn handle(&mut self, message: Candidate, _: &mut xtra::Context<Self>) -> 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>) -> 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<CLIENT_NAME_SIZE>,
}
impl Handler<PeerConnectionChanged> for ProximityPlayer {
type Return = ();
type Return = Result<String<CLIENT_NAME_SIZE>, ()>;
async fn handle(&mut self, message: PeerConnectionChanged, ctx: &mut xtra::Context<Self>) -> Self::Return {
let event = packet::Packet {
@ -222,15 +286,20 @@ impl Handler<PeerConnectionChanged> 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<PlayerConnected> 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<STAGE_GAME_NAME_SIZE>,
}
#[derive(IntoBytes, Immutable)]
#[derive(Clone, Copy, IntoBytes, Immutable)]
#[repr(C, packed)]
pub struct PeerConnectionChanged {
pub id: String<HYP_UUID_SIZE>,
pub id: UuidString,
pub connected: bool,
pub name: String<CLIENT_NAME_SIZE>,
}
#[newtype_enum]
#[derive(Debug)]
pub enum Event {
Offer {
pub id: String<HYP_UUID_SIZE>,
pub id: UuidString,
pub sdp: StdString,
},
Answer {
pub id: String<HYP_UUID_SIZE>,
pub id: UuidString,
pub sdp: StdString,
},
Candidate {
pub id: String<HYP_UUID_SIZE>,
pub id: UuidString,
pub candidate: StdString,
},
TargetChanged {
pub name: String<CLIENT_NAME_SIZE>,
},
}
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}"),
};

View file

@ -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