pub mod planet; pub mod staged_transform; pub mod part; pub mod was_updated; use std::any::TypeId; use std::collections::HashMap; use std::sync::OnceLock; use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering}; use std::time::Instant; use aeronet_transport::Transport; use aeronet_transport::lane::{LaneIndex, LaneKind}; use aeronet_websocket::tungstenite::Bytes; use avian2d::prelude::{AngularInertia, AngularVelocity, Collider, LinearVelocity, Mass, Position, Rotation}; use bevy::ecs::entity::{EntityHashMap, MapEntities}; use bevy::ecs::system::SystemState; use bevy::prelude::*; use bevy::reflect::DynamicTypePath; use postcard::{from_bytes, to_allocvec, to_slice, to_vec}; use crate::prelude::{App, Message}; use crate::shared::thrust::ThrustSolution; use serde::{Deserialize, Serialize}; use smolvec::SmolVec; use crate::shared::attachment::{Joint, JointOf, PartInShip, Peer, Ship, SnapOf, SnapOfJoint}; use crate::shared::config::planet::{Planet, PlanetSpring, PlanetSpringJoint}; use crate::shared::ecs::{CanCraft, CraftPartRequest, DragRequestEvent, Drill, Part, Player, PlayerStorage, SingleStorage, Temperature, ToggleDrillEvent}; use crate::shared::ecs::thruster::{Thruster, ThrusterOfPart}; use crate::shared::net::part::PartDto; use crate::shared::net::planet::PlanetDto; pub fn register_net(app: &mut App) { app .add_server_message::(LaneKind::ReliableOrdered) .add_server_message::(LaneKind::UnreliableSequenced) .add_server_message::(LaneKind::UnreliableSequenced) .add_client_message::(LaneKind::ReliableOrdered) .add_client_message::(LaneKind::ReliableOrdered) .add_client_message::(LaneKind::ReliableOrdered) .add_client_message::(LaneKind::ReliableOrdered) .add_systems(PostStartup, |srv_msg_reg: Res, client_msg_reg: Res| { debug!("network registration complete"); debug!("client registry: {:#?}", client_msg_reg); debug!("server registry: {:#?}", srv_msg_reg); }); } #[derive(Message, Clone, Deserialize, Serialize, TypePath, MapEntities)] pub struct Hi { #[entities] pub you_are: Entity, pub time_offset: f64, } pub fn setup_net(app: &mut App) { app.insert_resource(ServerMessageRegistry::default()); app.insert_resource(ClientMessageRegistry::default()); app.insert_resource(TransportLanes::default()); app.add_systems(Update, recv_from_server); app.add_systems(Update, recv_from_client); } #[derive(Message, Deref, Deserialize, Serialize)] pub struct ToClients { #[deref] pub message: T, pub targets: SendTargets, } #[derive(Message, Deref, Deserialize, Serialize)] pub struct FromClients { pub client_id: ClientId, #[deref] pub message: T, } #[derive(Deserialize, Serialize)] pub enum SendTargets { All, Single(ClientId), } #[derive(Deserialize, Serialize)] pub enum ClientId { Server, Client(Entity), } #[derive(Resource, Default)] pub struct TransportLanes { pub lanes: Vec } #[derive(Resource, Default)] pub struct ServerEntityMap { pub server_to_client: EntityHashMap, pub client_to_server: EntityHashMap, } #[derive(Resource, Default, Debug)] pub struct ServerMessageRegistry { forward: HashMap, reverse: HashMap, &mut World)>, } #[derive(Resource, Default, Debug)] pub struct ClientMessageRegistry { forward: HashMap, reverse: HashMap, ClientId, &mut World)>, } static COUNTER: AtomicU32 = AtomicU32::new(0); fn get_lane_index() -> LaneIndex { LaneIndex::new(COUNTER.fetch_add(1, Ordering::Relaxed)) } pub trait NetAppExt { fn add_mapped_server_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self; fn add_server_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self; fn add_mapped_client_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self; fn add_client_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self; } impl NetAppExt for App { fn add_mapped_server_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self { let mut registry = self.world_mut().resource_mut::(); register_mapped_server_message::(&mut registry); self.world_mut().resource_mut::().lanes.push(kind); self .add_message::>() .add_message::() .add_systems(Update, send_to_client::) } fn add_server_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self { let mut registry = self.world_mut().resource_mut::(); register_server_message::(&mut registry); self.world_mut().resource_mut::().lanes.push(kind); self .add_message::>() .add_message::() .add_systems(Update, send_to_client::) } fn add_mapped_client_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self { let mut registry = self.world_mut().resource_mut::(); register_client_message::(&mut registry); self.world_mut().resource_mut::().lanes.push(kind); self .add_message::>() .add_message::() .add_systems(Update, send_mapped_to_server::) } fn add_client_message Deserialize<'a>>(&mut self, kind: LaneKind) -> &mut Self { let mut registry = self.world_mut().resource_mut::(); register_client_message::(&mut registry); self.world_mut().resource_mut::().lanes.push(kind); self .add_message::>() .add_message::() .add_systems(Update, send_to_server::) } } fn register_mapped_server_message Deserialize<'a>>(registry: &mut ServerMessageRegistry) { let lane_index = get_lane_index(); registry.forward.insert(TypeId::of::(), lane_index); registry.reverse.insert(lane_index, |payload: Vec, world: &mut World| { let mut entity_map = world.resource_mut::(); let mut message = from_bytes::(&payload).expect(&format!("Failed to deserialize message of type {}", T::type_path())); message.map_entities(&mut entity_map.server_to_client); world.write_message(message).expect("Could not send message to game"); }); } fn register_server_message Deserialize<'a>>(registry: &mut ServerMessageRegistry) { let lane_index = get_lane_index(); registry.forward.insert(TypeId::of::(), lane_index); registry.reverse.insert(lane_index, |payload: Vec, world: &mut World| { let message = from_bytes::(&payload).expect(&format!("Failed to deserialize message of type {}", T::type_path())); world.write_message(message).expect("Could not send message to game"); }); } fn register_client_message Deserialize<'a>>(registry: &mut ClientMessageRegistry) { let lane_index = get_lane_index(); registry.forward.insert(TypeId::of::(), lane_index); registry.reverse.insert(lane_index, |payload: Vec, client_id: ClientId, world: &mut World| { let message = from_bytes::(&payload).expect(&format!("Failed to deserialize message of type {}", T::type_path())); world.write_message(FromClients { client_id, message, }).expect("Could not send message to game"); }); } fn send_to_client( mut messages: MessageReader>, mut clients: Query<(Entity, &mut Transport), With>, message_registry: Res, ) { for message in messages.read() { match &message.targets { SendTargets::All => { for (client_entity, mut transport) in &mut clients { transport.send.push( *message_registry.forward.get(&TypeId::of::()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), ).expect("Failed to send message"); } } SendTargets::Single(client) => { for (client_entity, mut transport) in &mut clients { if let ClientId::Client(client) = client && client_entity == *client { transport.send.push( *message_registry.forward.get(&TypeId::of::()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), ).expect("Failed to send message"); } } } } } } fn send_to_server( mut messages: MessageReader, mut sessions: Query<&mut Transport, Without>, message_registry: Res, ) { for message in messages.read() { for mut transport in &mut sessions { transport.send.push( *message_registry.forward.get(&TypeId::of::()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), ).expect("Failed to send message"); } } } fn send_mapped_to_server( mut messages: MessageReader, mut sessions: Query<&mut Transport, Without>, mut entity_map: ResMut, message_registry: Res, ) { for message in messages.read() { for mut transport in &mut sessions { let mut message = message.clone(); message.map_entities(&mut entity_map.client_to_server); transport.send.push( *message_registry.forward.get(&TypeId::of::()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), ).expect("Failed to send message"); } } } fn recv_from_server( world: &mut World ) { let mut system_state: SystemState<( Query<&mut Transport, Without>, Res, )> = SystemState::new(world); let (mut sessions, message_registry) = system_state.get_mut(world); let mut messages = SmolVec::new(); for mut transport in sessions.iter_mut() { for message in transport.recv.msgs.drain() { let payload = message.payload; let message_fn = message_registry.reverse.get(&message.lane).expect("Packet was sent across a lane that didn't have a message assigned to it yet"); messages.push((*message_fn, payload)); } for _ in transport.recv.acks.drain() { } } for (message_fn, payload) in messages { message_fn(payload, world); } } fn recv_from_client( world: &mut World ) { let mut system_state: SystemState<( Query<(Entity, &mut Transport), With>, Res, )> = SystemState::new(world); let (mut clients, message_registry) = system_state.get_mut(world); let mut messages = SmolVec::new(); for (client_entity, mut transport) in clients.iter_mut() { for message in transport.recv.msgs.drain() { let payload = message.payload; let message_fn = message_registry.reverse.get(&message.lane).expect("Packet was sent across a lane that didn't have a message assigned to it yet"); messages.push((payload, ClientId::Client(client_entity), *message_fn)); } for _ in transport.recv.acks.drain() { } } for (payload, client_id, message_fn) in messages { message_fn(payload, client_id, world); } }