A multiplayer VR framework w/voice chat

tidy up and multiplayer now works

phaz.uk ef6de1af 0e76de07

verified
+155 -22
Cargo.lock
··· 1737 1737 ] 1738 1738 1739 1739 [[package]] 1740 - name = "client" 1741 - version = "0.1.0" 1742 - dependencies = [ 1743 - "anyhow", 1744 - "bevy", 1745 - "dotenvy", 1746 - "felix-net", 1747 - ] 1748 - 1749 - [[package]] 1750 1740 name = "codespan-reporting" 1751 1741 version = "0.12.0" 1752 1742 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2233 2223 ] 2234 2224 2235 2225 [[package]] 2226 + name = "felix-client" 2227 + version = "0.1.0" 2228 + dependencies = [ 2229 + "anyhow", 2230 + "bevy", 2231 + "dotenvy", 2232 + "felix-net", 2233 + "tokio", 2234 + ] 2235 + 2236 + [[package]] 2236 2237 name = "felix-net" 2237 2238 version = "0.1.0" 2238 2239 dependencies = [ ··· 2241 2242 ] 2242 2243 2243 2244 [[package]] 2245 + name = "felix-server" 2246 + version = "0.1.0" 2247 + dependencies = [ 2248 + "anyhow", 2249 + "bevy_math", 2250 + "dotenvy", 2251 + "felix-net", 2252 + "nanoid", 2253 + ] 2254 + 2255 + [[package]] 2244 2256 name = "find-msvc-tools" 2245 2257 version = "0.1.5" 2246 2258 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2996 3008 dependencies = [ 2997 3009 "adler2", 2998 3010 "simd-adler32", 3011 + ] 3012 + 3013 + [[package]] 3014 + name = "mio" 3015 + version = "1.1.1" 3016 + source = "registry+https://github.com/rust-lang/crates.io-index" 3017 + checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" 3018 + dependencies = [ 3019 + "libc", 3020 + "wasi", 3021 + "windows-sys 0.61.2", 2999 3022 ] 3000 3023 3001 3024 [[package]] ··· 4119 4142 ] 4120 4143 4121 4144 [[package]] 4122 - name = "server" 4123 - version = "0.1.0" 4124 - dependencies = [ 4125 - "anyhow", 4126 - "bevy_math", 4127 - "dotenvy", 4128 - "felix-net", 4129 - "nanoid", 4130 - ] 4131 - 4132 - [[package]] 4133 4145 name = "sharded-slab" 4134 4146 version = "0.1.7" 4135 4147 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4143 4155 version = "1.3.0" 4144 4156 source = "registry+https://github.com/rust-lang/crates.io-index" 4145 4157 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 4158 + 4159 + [[package]] 4160 + name = "signal-hook-registry" 4161 + version = "1.4.7" 4162 + source = "registry+https://github.com/rust-lang/crates.io-index" 4163 + checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" 4164 + dependencies = [ 4165 + "libc", 4166 + ] 4146 4167 4147 4168 [[package]] 4148 4169 name = "simd-adler32" ··· 4213 4234 checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" 4214 4235 dependencies = [ 4215 4236 "serde", 4237 + ] 4238 + 4239 + [[package]] 4240 + name = "socket2" 4241 + version = "0.6.1" 4242 + source = "registry+https://github.com/rust-lang/crates.io-index" 4243 + checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" 4244 + dependencies = [ 4245 + "libc", 4246 + "windows-sys 0.60.2", 4216 4247 ] 4217 4248 4218 4249 [[package]] ··· 4422 4453 checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 4423 4454 4424 4455 [[package]] 4456 + name = "tokio" 4457 + version = "1.48.0" 4458 + source = "registry+https://github.com/rust-lang/crates.io-index" 4459 + checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" 4460 + dependencies = [ 4461 + "bytes", 4462 + "libc", 4463 + "mio", 4464 + "parking_lot", 4465 + "pin-project-lite", 4466 + "signal-hook-registry", 4467 + "socket2", 4468 + "tokio-macros", 4469 + "windows-sys 0.61.2", 4470 + ] 4471 + 4472 + [[package]] 4473 + name = "tokio-macros" 4474 + version = "2.6.0" 4475 + source = "registry+https://github.com/rust-lang/crates.io-index" 4476 + checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" 4477 + dependencies = [ 4478 + "proc-macro2", 4479 + "quote", 4480 + "syn", 4481 + ] 4482 + 4483 + [[package]] 4425 4484 name = "toml_datetime" 4426 4485 version = "0.7.5+spec-1.1.0" 4427 4486 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5365 5424 5366 5425 [[package]] 5367 5426 name = "windows-sys" 5427 + version = "0.60.2" 5428 + source = "registry+https://github.com/rust-lang/crates.io-index" 5429 + checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" 5430 + dependencies = [ 5431 + "windows-targets 0.53.5", 5432 + ] 5433 + 5434 + [[package]] 5435 + name = "windows-sys" 5368 5436 version = "0.61.2" 5369 5437 source = "registry+https://github.com/rust-lang/crates.io-index" 5370 5438 checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" ··· 5396 5464 "windows_aarch64_gnullvm 0.52.6", 5397 5465 "windows_aarch64_msvc 0.52.6", 5398 5466 "windows_i686_gnu 0.52.6", 5399 - "windows_i686_gnullvm", 5467 + "windows_i686_gnullvm 0.52.6", 5400 5468 "windows_i686_msvc 0.52.6", 5401 5469 "windows_x86_64_gnu 0.52.6", 5402 5470 "windows_x86_64_gnullvm 0.52.6", ··· 5404 5472 ] 5405 5473 5406 5474 [[package]] 5475 + name = "windows-targets" 5476 + version = "0.53.5" 5477 + source = "registry+https://github.com/rust-lang/crates.io-index" 5478 + checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" 5479 + dependencies = [ 5480 + "windows-link 0.2.1", 5481 + "windows_aarch64_gnullvm 0.53.1", 5482 + "windows_aarch64_msvc 0.53.1", 5483 + "windows_i686_gnu 0.53.1", 5484 + "windows_i686_gnullvm 0.53.1", 5485 + "windows_i686_msvc 0.53.1", 5486 + "windows_x86_64_gnu 0.53.1", 5487 + "windows_x86_64_gnullvm 0.53.1", 5488 + "windows_x86_64_msvc 0.53.1", 5489 + ] 5490 + 5491 + [[package]] 5407 5492 name = "windows-threading" 5408 5493 version = "0.1.0" 5409 5494 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5434 5519 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 5435 5520 5436 5521 [[package]] 5522 + name = "windows_aarch64_gnullvm" 5523 + version = "0.53.1" 5524 + source = "registry+https://github.com/rust-lang/crates.io-index" 5525 + checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" 5526 + 5527 + [[package]] 5437 5528 name = "windows_aarch64_msvc" 5438 5529 version = "0.42.2" 5439 5530 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5446 5537 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 5447 5538 5448 5539 [[package]] 5540 + name = "windows_aarch64_msvc" 5541 + version = "0.53.1" 5542 + source = "registry+https://github.com/rust-lang/crates.io-index" 5543 + checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" 5544 + 5545 + [[package]] 5449 5546 name = "windows_i686_gnu" 5450 5547 version = "0.42.2" 5451 5548 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5458 5555 checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 5459 5556 5460 5557 [[package]] 5558 + name = "windows_i686_gnu" 5559 + version = "0.53.1" 5560 + source = "registry+https://github.com/rust-lang/crates.io-index" 5561 + checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" 5562 + 5563 + [[package]] 5461 5564 name = "windows_i686_gnullvm" 5462 5565 version = "0.52.6" 5463 5566 source = "registry+https://github.com/rust-lang/crates.io-index" 5464 5567 checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 5465 5568 5466 5569 [[package]] 5570 + name = "windows_i686_gnullvm" 5571 + version = "0.53.1" 5572 + source = "registry+https://github.com/rust-lang/crates.io-index" 5573 + checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" 5574 + 5575 + [[package]] 5467 5576 name = "windows_i686_msvc" 5468 5577 version = "0.42.2" 5469 5578 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5476 5585 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 5477 5586 5478 5587 [[package]] 5588 + name = "windows_i686_msvc" 5589 + version = "0.53.1" 5590 + source = "registry+https://github.com/rust-lang/crates.io-index" 5591 + checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" 5592 + 5593 + [[package]] 5479 5594 name = "windows_x86_64_gnu" 5480 5595 version = "0.42.2" 5481 5596 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5488 5603 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 5489 5604 5490 5605 [[package]] 5606 + name = "windows_x86_64_gnu" 5607 + version = "0.53.1" 5608 + source = "registry+https://github.com/rust-lang/crates.io-index" 5609 + checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" 5610 + 5611 + [[package]] 5491 5612 name = "windows_x86_64_gnullvm" 5492 5613 version = "0.42.2" 5493 5614 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5500 5621 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 5501 5622 5502 5623 [[package]] 5624 + name = "windows_x86_64_gnullvm" 5625 + version = "0.53.1" 5626 + source = "registry+https://github.com/rust-lang/crates.io-index" 5627 + checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" 5628 + 5629 + [[package]] 5503 5630 name = "windows_x86_64_msvc" 5504 5631 version = "0.42.2" 5505 5632 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5510 5637 version = "0.52.6" 5511 5638 source = "registry+https://github.com/rust-lang/crates.io-index" 5512 5639 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 5640 + 5641 + [[package]] 5642 + name = "windows_x86_64_msvc" 5643 + version = "0.53.1" 5644 + source = "registry+https://github.com/rust-lang/crates.io-index" 5645 + checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" 5513 5646 5514 5647 [[package]] 5515 5648 name = "winit"
+2 -1
client/Cargo.toml
··· 1 1 [package] 2 - name = "client" 2 + name = "felix-client" 3 3 version = "0.1.0" 4 4 edition = "2024" 5 5 ··· 8 8 bevy = "0.17.3" 9 9 dotenvy = "0.15.7" 10 10 felix-net = { path = '../net' } 11 + tokio = { version = "1.48.0", features = ["full"] }
+3
client/src/components/mod.rs
··· 1 + pub mod debug_camera; 2 + pub mod network_interface; 3 + pub mod remote_player;
+98
client/src/components/network_interface.rs
··· 1 + use std::collections::HashMap; 2 + 3 + use bevy::prelude::*; 4 + use felix_net::{packet::PacketTypes, packets::update_server_position::UpdateServerPositions}; 5 + 6 + use crate::{debug_camera::DebugCamera, net::{NetClientCommand, connection::Connection}, remote_player::RemotePlayer}; 7 + 8 + pub fn fixed_update( 9 + mut query: Query<(&mut DebugCamera, &mut Transform)>, 10 + mut networking: Query<&mut Connection>, 11 + 12 + mut commands: Commands, 13 + mut meshes: ResMut<Assets<Mesh>>, 14 + mut materials: ResMut<Assets<StandardMaterial>>, 15 + 16 + players: Query<(Entity, &mut RemotePlayer)> 17 + ){ 18 + let ( _, transform ) = query.single_mut().unwrap(); 19 + let mut net_manager = networking.single_mut().unwrap(); 20 + 21 + let update_pos_packet = UpdateServerPositions { 22 + position: transform.translation.clone(), 23 + rotation: transform.rotation.clone() 24 + }; 25 + 26 + net_manager.try_send_unreliable(update_pos_packet).unwrap(); 27 + 28 + 29 + if let Ok(ev) = net_manager.recv_event(){ 30 + match ev{ 31 + NetClientCommand::Connected(id) => { 32 + println!("[INFO] Connected to server as {}", id); 33 + } 34 + NetClientCommand::Disconnected => { 35 + println!("[WARN] Disconnected from server."); 36 + } 37 + NetClientCommand::RecvPacket(packet) => { 38 + match packet{ 39 + PacketTypes::PlayerJoinPacket(packet) => { 40 + join_players(vec![packet.id], &mut commands, &mut meshes, &mut materials); 41 + } 42 + PacketTypes::PlayerListPacket(packet) => { 43 + join_players(packet.ids, &mut commands, &mut meshes, &mut materials); 44 + } 45 + PacketTypes::PlayerLeavePacket(packet) => { 46 + leave_player(packet.id, &mut commands, players); 47 + } 48 + PacketTypes::UpdateClientsPositions(packet) => { 49 + let mut map = HashMap::new(); 50 + 51 + for ( id, pos, rot ) in packet.players{ 52 + map.insert(id, (pos, rot)); } 53 + 54 + for ( _, mut player ) in players{ 55 + let ( pos, rot ) = map.get(&player.id).unwrap(); 56 + 57 + player.pos = *pos; 58 + player.rot = *rot; 59 + } 60 + } 61 + _ => {} 62 + } 63 + } 64 + } 65 + } 66 + } 67 + 68 + fn join_players( 69 + players: Vec<String>, 70 + 71 + commands: &mut Commands, 72 + meshes: &mut ResMut<Assets<Mesh>>, 73 + materials: &mut ResMut<Assets<StandardMaterial>>, 74 + ){ 75 + for id in players{ 76 + commands.spawn(( 77 + Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))), 78 + MeshMaterial3d(materials.add(Color::WHITE)), 79 + Transform::from_xyz(0.0, 0.0, 0.0), 80 + RemotePlayer { id, ..Default::default() } 81 + )); 82 + } 83 + } 84 + 85 + fn leave_player( 86 + id: String, 87 + 88 + commands: &mut Commands, 89 + 90 + players: Query<(Entity, &mut RemotePlayer)> 91 + ){ 92 + for ( entity, player ) in players{ 93 + if id == player.id{ 94 + commands.entity(entity).despawn(); 95 + break; 96 + } 97 + } 98 + }
+19
client/src/components/remote_player.rs
··· 1 + use bevy::{ecs::{component::Component, system::Query}, math::{Quat, Vec3}, transform::components::Transform}; 2 + 3 + #[derive(Component, Debug, Default)] 4 + pub struct RemotePlayer{ 5 + pub id: String, 6 + 7 + pub pos: Vec3, 8 + pub rot: Quat 9 + } 10 + 11 + 12 + pub fn update( 13 + players: Query<(&mut Transform, &RemotePlayer)> 14 + ){ 15 + for ( mut transform, player ) in players{ 16 + transform.translation = Vec3::lerp(transform.translation, player.pos, 0.5); 17 + transform.rotation = Quat::lerp(transform.rotation, player.rot, 0.5); 18 + } 19 + }
-12
client/src/debug_camera.rs client/src/components/debug_camera.rs
··· 2 2 3 3 use bevy::{ input::mouse::MouseMotion, prelude::* }; 4 4 5 - use crate::net::component::ClientNetworkingManager; 6 - 7 5 #[derive(Component)] 8 6 pub struct DebugCamera{ 9 7 pitch: f32, ··· 17 15 yaw: -PI / 2.0 18 16 } 19 17 } 20 - } 21 - 22 - pub fn fixed_update( 23 - mut query: Query<(&mut DebugCamera, &mut Transform)>, 24 - mut networking: Query<&mut ClientNetworkingManager> 25 - ){ 26 - let ( _, transform ) = query.single_mut().unwrap(); 27 - let net_manager = networking.single_mut().unwrap(); 28 - 29 - net_manager.update_server_position(transform.translation.clone(), transform.rotation.clone()); 30 18 } 31 19 32 20 pub fn update(
+6 -13
client/src/main.rs
··· 1 - use std::sync::mpsc::channel; 2 - 3 1 use bevy::{DefaultPlugins, app::{App, FixedUpdate, Startup, Update}, ecs::system::Commands}; 4 2 5 - use crate::{net::component::ClientNetworkingManager, setup::setup}; 6 - 7 - mod debug_camera; 3 + use crate::{components::{debug_camera, network_interface, remote_player}, setup::setup}; 8 4 5 + mod components; 9 6 mod setup; 10 7 mod net; 11 8 12 9 fn main() { 13 10 dotenvy::dotenv().unwrap(); 14 11 15 - let (sender, recv) = channel(); 16 - let net_manager = ClientNetworkingManager::from(sender); 17 - 18 - net::handle_net(recv).expect("Network Module Failed."); 19 - 20 12 App::new() 21 13 .add_plugins(DefaultPlugins) 22 14 .add_systems(Startup, setup) 23 - .add_systems(Startup, move | mut commands: Commands | { 24 - commands.spawn(net_manager.clone()); 15 + .add_systems(Startup, move | mut commands: Commands |{ 16 + commands.spawn(net::handle_net().expect("Network Module Failed.")); 25 17 }) 26 18 .add_systems(Update, debug_camera::update) 27 - .add_systems(FixedUpdate, debug_camera::fixed_update) 19 + .add_systems(Update, remote_player::update) 20 + .add_systems(FixedUpdate, network_interface::fixed_update) 28 21 .run(); 29 22 }
-27
client/src/net/component.rs
··· 1 - use std::sync::mpsc::Sender; 2 - 3 - use bevy::{ecs::component::Component, math::{Quat, Vec3}}; 4 - 5 - #[derive(Debug, Clone)] 6 - pub enum ClientNetworkingManagerCommand{ 7 - UpdatePlayerPosition(Vec3, Quat), 8 - } 9 - 10 - #[derive(Component, Debug, Clone)] 11 - pub struct ClientNetworkingManager{ 12 - cmd: Sender<ClientNetworkingManagerCommand> 13 - } 14 - 15 - impl From<Sender<ClientNetworkingManagerCommand>> for ClientNetworkingManager{ 16 - fn from(value: Sender<ClientNetworkingManagerCommand>) -> Self { 17 - Self { 18 - cmd: value 19 - } 20 - } 21 - } 22 - 23 - impl ClientNetworkingManager{ 24 - pub fn update_server_position(&self, pos: Vec3, rot: Quat){ 25 - self.cmd.send(ClientNetworkingManagerCommand::UpdatePlayerPosition(pos, rot)).unwrap(); 26 - } 27 - }
+36 -19
client/src/net/connection.rs
··· 1 - use std::{io::{Read, Write}, net::{SocketAddr, TcpStream, UdpSocket}, sync::mpsc::Sender, thread}; 1 + use std::{io::{Read, Write}, net::{SocketAddr, TcpStream, UdpSocket}, thread}; 2 + use bevy::ecs::component::Component; 3 + use tokio::sync::broadcast::{self, Receiver, Sender}; 2 4 3 - use felix_net::{packet::{self, Packet, PacketTypes}, packets::{link_udp::LinkUDP, notify_connection_info::NotifyConnectionInfo}}; 5 + use felix_net::{buffer::Buffer, packet::{self, Packet, PacketTypes}, packets::{link_udp::LinkUDP, notify_connection_info::NotifyConnectionInfo}}; 4 6 5 7 use crate::net::NetClientCommand; 6 8 7 9 8 - #[derive(Debug)] 10 + #[derive(Component, Debug)] 9 11 pub struct Connection{ 10 12 tcp: TcpStream, 11 13 12 14 udp: UdpSocket, 13 15 udp_server_address: SocketAddr, 14 16 17 + net_recv: Receiver<NetClientCommand>, 18 + 15 19 pub id: String 16 20 } 17 21 18 22 impl Connection{ 19 - pub fn new( stream: TcpStream, udp: UdpSocket, udp_server_address: SocketAddr, cmd: Sender<NetClientCommand> ) -> Self{ 23 + pub fn new( stream: TcpStream, udp: UdpSocket, udp_server_address: SocketAddr ) -> Self{ 24 + let ( event_sender, event_recv ) = broadcast::channel(32); 25 + 20 26 let mut conn = Self { 21 27 tcp: stream, 22 28 23 29 udp, 24 30 udp_server_address, 25 31 32 + net_recv: event_recv, 33 + 26 34 id: "".to_owned() 27 35 }; 28 36 29 - conn.start_listener_thread(cmd).unwrap(); 37 + conn.start_listener_thread(event_sender).unwrap(); 30 38 31 39 let packet = NotifyConnectionInfo { id: conn.id.clone() }; 32 40 conn.send_reliable(packet).unwrap(); ··· 49 57 while let Ok((length, addr)) = udp_1.recv_from(&mut buf){ 50 58 if addr != srv_addr{ continue; } 51 59 52 - let msg = &buf[0..length]; 53 - let packet = packet::parse(msg.into()); 60 + let mut msg: Buffer = (&buf[0..length]).into(); 54 61 55 - cmd_1.send(NetClientCommand::RecvPacket(packet)).unwrap(); 62 + while msg.left() > 0{ 63 + let packet = packet::parse(&mut msg); 64 + cmd_1.send(NetClientCommand::RecvPacket(packet)).unwrap(); 65 + } 56 66 } 57 67 }); 58 68 ··· 62 72 while let Ok(length) = tcp.read(&mut buf){ 63 73 if length == 0 { break; } 64 74 65 - let msg = &buf[0..length]; 66 - let packet = packet::parse(msg.into()); 75 + let mut msg: Buffer = (&buf[0..length]).into(); 76 + 77 + while msg.left() > 0{ 78 + let packet = packet::parse(&mut msg); 67 79 68 - match packet{ 69 - PacketTypes::NotifyConnectionInfo(info) => { 70 - cmd.send(NetClientCommand::Connected(info.id.clone())).unwrap(); 80 + match packet{ 81 + PacketTypes::NotifyConnectionInfo(info) => { 82 + cmd.send(NetClientCommand::Connected(info.id.clone())).unwrap(); 71 83 72 - let packet = LinkUDP { id: info.id }; 73 - let packet: Vec<_> = packet.to_buf().into(); 84 + let packet = LinkUDP { id: info.id }; 85 + let packet: Vec<_> = packet.to_buf().into(); 74 86 75 - udp.send_to(&packet, "127.0.0.1:2603").unwrap(); 76 - }, 77 - _ => { 78 - cmd.send(NetClientCommand::RecvPacket(packet)).unwrap(); 87 + udp.send_to(&packet, "127.0.0.1:2603").unwrap(); 88 + }, 89 + _ => { 90 + cmd.send(NetClientCommand::RecvPacket(packet)).unwrap(); 91 + } 79 92 } 80 93 } 81 94 } ··· 84 97 }); 85 98 86 99 Ok(()) 100 + } 101 + 102 + pub fn recv_event(&mut self) -> anyhow::Result<NetClientCommand>{ 103 + Ok(self.net_recv.try_recv()?) 87 104 } 88 105 89 106 pub fn send_reliable(&mut self, packet: impl Packet) -> anyhow::Result<()>{
+11 -59
client/src/net/mod.rs
··· 1 - use std::{net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpStream, UdpSocket}, sync::mpsc::{Receiver, channel}, thread}; 1 + use std::{env, net::{TcpStream, ToSocketAddrs, UdpSocket}}; 2 2 3 - use bevy::math::{Quat, Vec3}; 4 - use felix_net::{packet::PacketTypes, packets::update_server_position::UpdateServerPositions}; 3 + use bevy::prelude::*; 4 + use felix_net::packet::PacketTypes; 5 5 6 - use crate::net::{component::ClientNetworkingManagerCommand, connection::Connection}; 6 + use crate::net::connection::Connection; 7 7 8 - pub mod component; 9 - mod connection; 8 + pub mod connection; 10 9 10 + #[derive(Debug, Clone)] 11 11 pub enum NetClientCommand{ 12 12 Connected(String), 13 13 Disconnected, 14 - UpdatePlayerPosition(Vec3, Quat), 15 14 RecvPacket(PacketTypes) 16 15 } 17 16 18 - pub fn ipv4_address(a: u8, b: u8, c: u8, d: u8, port: u16) -> SocketAddr{ 19 - SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(a, b, c, d), port)) 20 - } 17 + pub fn handle_net() -> anyhow::Result<Connection>{ 18 + let addr = env::var("HOST")?.to_socket_addrs()?.nth(0).unwrap(); 21 19 22 - pub fn handle_net(cmd: Receiver<ClientNetworkingManagerCommand>) -> anyhow::Result<()>{ 23 - let tcp = TcpStream::connect("127.0.0.1:2603")?; 20 + let tcp = TcpStream::connect(addr)?; 24 21 let udp = UdpSocket::bind("0.0.0.0:0")?; 25 22 26 - let ( sender_cmd, recv ) = channel(); 27 - let sender_cmd_1 = sender_cmd.clone(); 28 - 29 - thread::spawn(move || { 30 - while let Ok(cmd) = cmd.recv(){ 31 - match cmd{ 32 - ClientNetworkingManagerCommand::UpdatePlayerPosition(pos, rot) => 33 - sender_cmd_1.send(NetClientCommand::UpdatePlayerPosition(pos, rot)).unwrap(), 34 - } 35 - } 36 - }); 37 - 38 - thread::spawn(move || { 39 - let mut conn = Connection::new(tcp, udp, ipv4_address(127, 0, 0, 1, 2603), sender_cmd); 40 - 41 - while let Ok(cmd) = recv.recv(){ 42 - match cmd{ 43 - NetClientCommand::Connected(id) => { 44 - println!("[INFO] Connected to server as {}", id); 45 - conn.id = id; 46 - }, 47 - NetClientCommand::Disconnected => { 48 - println!("[WARN] Disconnected from server."); 49 - }, 50 - NetClientCommand::UpdatePlayerPosition(pos, rot) => { 51 - let packet = UpdateServerPositions { position: pos, rotation: rot }; 52 - conn.try_send_unreliable(packet).unwrap(); 53 - }, 54 - NetClientCommand::RecvPacket(packet) => { 55 - match packet{ 56 - PacketTypes::PlayerJoinPacket(player) => { 57 - dbg!(player); 58 - }, 59 - PacketTypes::PlayerListPacket(players) => { 60 - dbg!(players); 61 - }, 62 - PacketTypes::PlayerLeavePacket(player) => { 63 - dbg!(player); 64 - }, 65 - _ => {} 66 - } 67 - } 68 - } 69 - } 70 - }); 71 - 72 - Ok(()) 23 + let conn = Connection::new(tcp, udp, addr); 24 + Ok(conn) 73 25 }
+4
net/src/buffer.rs
··· 11 11 Self { dat: vec![], pointer: 0 } 12 12 } 13 13 14 + pub fn left(&self) -> usize{ 15 + self.dat.len() - self.pointer 16 + } 17 + 14 18 pub fn pointer(&mut self, val: usize){ 15 19 self.pointer = val; 16 20 }
+3 -3
net/src/packet.rs
··· 5 5 } 6 6 }; 7 7 8 - #[derive(Debug)] 8 + #[derive(Debug, Clone)] 9 9 pub enum PacketTypes{ 10 10 NotifyConnectionInfo(NotifyConnectionInfo), 11 11 LinkUDP(LinkUDP), ··· 21 21 } 22 22 23 23 pub trait Packet{ 24 - fn from_buf(buf: Buffer) -> Self; 24 + fn from_buf(buf: &mut Buffer) -> Self; 25 25 fn to_buf(&self) -> Buffer; 26 26 } 27 27 28 - pub fn parse(mut buf: Buffer) -> PacketTypes{ 28 + pub fn parse(buf: &mut Buffer) -> PacketTypes{ 29 29 let id = buf.get_u16(); 30 30 31 31 match id{
+2 -2
net/src/packets/notify_connection_info.rs
··· 1 1 use crate::{buffer::Buffer, packet::Packet}; 2 2 3 - #[derive(Debug)] 3 + #[derive(Debug, Clone)] 4 4 pub struct NotifyConnectionInfo{ 5 5 pub id: String 6 6 } ··· 14 14 buf 15 15 } 16 16 17 - fn from_buf(mut buf: Buffer) -> Self { 17 + fn from_buf(buf: &mut Buffer) -> Self { 18 18 Self { id: buf.get_str() } 19 19 } 20 20 }
+2 -2
net/src/packets/null.rs
··· 1 1 use crate::{buffer::Buffer, packet::Packet}; 2 2 3 - #[derive(Debug)] 3 + #[derive(Debug, Clone)] 4 4 pub struct Null; 5 5 6 6 impl Packet for Null{ ··· 8 8 Buffer::empty() 9 9 } 10 10 11 - fn from_buf(_: Buffer) -> Self { 11 + fn from_buf(_buf: &mut Buffer) -> Self { 12 12 Self {} 13 13 } 14 14 }
+1 -1
net/src/packets/player_join_packet.rs
··· 14 14 buf 15 15 } 16 16 17 - fn from_buf(mut buf: Buffer) -> Self { 17 + fn from_buf(buf: &mut Buffer) -> Self { 18 18 Self { id: buf.get_str() } 19 19 } 20 20 }
+1 -1
net/src/packets/player_leave_packet.rs
··· 14 14 buf 15 15 } 16 16 17 - fn from_buf(mut buf: Buffer) -> Self { 17 + fn from_buf(buf: &mut Buffer) -> Self { 18 18 Self { id: buf.get_str() } 19 19 } 20 20 }
+1 -1
net/src/packets/player_list_packet.rs
··· 15 15 buf 16 16 } 17 17 18 - fn from_buf(mut buf: Buffer) -> Self { 18 + fn from_buf(buf: &mut Buffer) -> Self { 19 19 let mut ids = vec![]; 20 20 let length = buf.get_u32(); 21 21
+1 -1
net/src/packets/update_clients_positions.rs
··· 22 22 buf 23 23 } 24 24 25 - fn from_buf(mut buf: Buffer) -> Self { 25 + fn from_buf(buf: &mut Buffer) -> Self { 26 26 let mut players = vec![]; 27 27 28 28 for _ in 0..buf.get_u32(){
+2 -2
net/src/packets/update_server_position.rs
··· 2 2 3 3 use crate::{buffer::Buffer, packet::Packet}; 4 4 5 - #[derive(Debug)] 5 + #[derive(Debug, Clone)] 6 6 pub struct UpdateServerPositions{ 7 7 pub position: Vec3, 8 8 pub rotation: Quat ··· 19 19 buf 20 20 } 21 21 22 - fn from_buf(mut buf: Buffer) -> Self { 22 + fn from_buf(buf: &mut Buffer) -> Self { 23 23 Self { 24 24 position: buf.get_vec3(), 25 25 rotation: buf.get_quat()
+1 -1
server/Cargo.toml
··· 1 1 [package] 2 - name = "server" 2 + name = "felix-server" 3 3 version = "0.1.0" 4 4 edition = "2024" 5 5
+6 -4
server/src/net/connection.rs
··· 1 1 use std::{io::{Read, Write}, net::{SocketAddr, TcpStream}, sync::mpsc::Sender, thread}; 2 2 3 3 use bevy_math::{Quat, Vec3}; 4 - use felix_net::{packet::{self, Packet, PacketTypes}, packets::notify_connection_info::NotifyConnectionInfo}; 4 + use felix_net::{buffer::Buffer, packet::{self, Packet, PacketTypes}, packets::notify_connection_info::NotifyConnectionInfo}; 5 5 use nanoid::nanoid; 6 6 7 7 use crate::net::NetServerCommand; ··· 49 49 let mut buf = [0; 1024]; 50 50 while let Ok(length) = stream.read(&mut buf) { 51 51 if length == 0 { break; } 52 - let msg = &buf[0..length]; 52 + let mut msg: Buffer = (&buf[0..length]).into(); 53 53 54 - let packet = packet::parse(msg.into()); 55 - cmd.send(NetServerCommand::RecvOverTCP(id.clone(), packet)).unwrap(); 54 + while msg.left() > 0{ 55 + let packet = packet::parse(&mut msg); 56 + cmd.send(NetServerCommand::RecvOverTCP(id.clone(), packet)).unwrap(); 57 + } 56 58 } 57 59 58 60 cmd.send(NetServerCommand::PlayerDisconnect(id)).unwrap();
+11 -9
server/src/net/mod.rs
··· 1 1 use std::{collections::HashMap, env, net::{SocketAddr, TcpListener, TcpStream, UdpSocket}, sync::mpsc::channel, thread, time::Duration}; 2 2 3 - use felix_net::{packet::{self, PacketTypes}, packets::{player_join_packet::PlayerJoinPacket, player_leave_packet::PlayerLeavePacket, player_list_packet::PlayerListPacket, update_clients_positions::UpdateClientsPositions}}; 3 + use felix_net::{buffer::Buffer, packet::{self, PacketTypes}, packets::{player_join_packet::PlayerJoinPacket, player_leave_packet::PlayerLeavePacket, player_list_packet::PlayerListPacket, update_clients_positions::UpdateClientsPositions}}; 4 4 5 5 use crate::net::connection::Connection; 6 6 ··· 49 49 50 50 loop { 51 51 let ( length, address ) = udp_listener.recv_from(&mut buf).unwrap(); 52 + let mut msg: Buffer = (&buf[0..length]).into(); 52 53 53 - let msg = &buf[0..length]; 54 - let packet = packet::parse(msg.into()); 54 + while msg.left() > 0{ 55 + let packet = packet::parse(&mut msg); 55 56 56 - match packet{ 57 - PacketTypes::LinkUDP(info) => { 58 - sender_1.send(NetServerCommand::LinkUDP(info.id, address)).unwrap(); 59 - } 60 - _ => { 61 - sender_1.send(NetServerCommand::RecvOverUDP(address, packet)).unwrap(); 57 + match packet{ 58 + PacketTypes::LinkUDP(info) => { 59 + sender_1.send(NetServerCommand::LinkUDP(info.id, address)).unwrap(); 60 + } 61 + _ => { 62 + sender_1.send(NetServerCommand::RecvOverUDP(address, packet)).unwrap(); 63 + } 62 64 } 63 65 } 64 66 }