From 4db82f328b50ec742f9beca9bcf395c70a7e7195 Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Sun, 6 Jul 2025 18:29:58 -0400 Subject: [PATCH] Create generic distribution system Still incredibly basic and only handles initial distribution and spawning with no relationships or anything. --- src/game/plugin.rs | 2 ++ src/net/distribution.rs | 49 +++++++++++++++++++++++++++++++++++++++++ src/net/mod.rs | 6 ++++- src/net/plugin.rs | 9 ++------ src/net/state.rs | 8 +++++++ 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 src/net/distribution.rs create mode 100644 src/net/state.rs diff --git a/src/game/plugin.rs b/src/game/plugin.rs index 0e920fd..d879c20 100644 --- a/src/game/plugin.rs +++ b/src/game/plugin.rs @@ -91,6 +91,8 @@ impl Plugin for GamePlugin { ), ); + Seed::register(app); + match self.source { DataSource::Address(peer) => { info!("Will retrieve seed from peer => {peer}"); diff --git a/src/net/distribution.rs b/src/net/distribution.rs new file mode 100644 index 0000000..e5e512d --- /dev/null +++ b/src/net/distribution.rs @@ -0,0 +1,49 @@ +use bevy::prelude::*; + +use super::{ + packet::{InboundPacket, OutboundPacket, Packet}, + peer::Peer, + state::NetworkState, +}; + +fn spawner> + Component>( + mut inbound: EventReader, + mut commands: Commands, +) { + for packet in inbound.read() { + if let Ok(entity) = T::try_from(packet.0.message.clone()) { + commands.spawn(entity); + } + } +} + +fn sender> + Component + Clone>( + peers: Query<&Peer, Added>, + entities: Query<&T>, + mut outbound: EventWriter, +) { + for peer in peers { + for entity in entities { + outbound.write(OutboundPacket(Packet::new( + (*entity).clone().into(), + peer.uuid, + ))); + } + } +} + +pub trait Networked: Into> + TryFrom> + Component + Clone { + fn register(app: &mut App); +} + +impl Networked for T +where + T: Into> + TryFrom> + Component + Clone, +{ + fn register(app: &mut App) { + app.add_systems( + FixedUpdate, + (sender::, spawner::).run_if(in_state(NetworkState::MultiPlayer)), + ); + } +} diff --git a/src/net/mod.rs b/src/net/mod.rs index 678172f..e4475c4 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -1,14 +1,18 @@ +mod distribution; mod io; mod packet; mod peer; mod plugin; mod queues; mod socket; +mod state; mod thread; #[allow(unused_imports)] pub mod prelude { + pub use super::distribution::Networked; pub use super::packet::{InboundPacket, OutboundPacket, Packet}; pub use super::peer::{Peer, PeerReceiveTiming, PeerSendTiming}; - pub use super::plugin::{NetIOPlugin, NetworkState}; + pub use super::plugin::NetIOPlugin; + pub use super::state::NetworkState; } diff --git a/src/net/plugin.rs b/src/net/plugin.rs index bbe807f..9cf00b1 100644 --- a/src/net/plugin.rs +++ b/src/net/plugin.rs @@ -4,20 +4,15 @@ use bevy::prelude::*; use uuid::Uuid; use super::{ + distribution::Networked, io::{Config, handle_network_input, handle_network_output, heartbeat, timeout}, packet::{InboundPacket, OutboundPacket}, peer::{Peer, PeerChangeEvent, PeerMap, handle_new_peer, handle_peer_change}, queues::{NetworkReceive, NetworkSend}, socket::bind_socket, + state::NetworkState, }; -#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)] -pub enum NetworkState { - #[default] - SinglePlayer, - MultiPlayer, -} - pub struct NetIOPlugin { listen: u16, peer: Option, diff --git a/src/net/state.rs b/src/net/state.rs new file mode 100644 index 0000000..2321bbe --- /dev/null +++ b/src/net/state.rs @@ -0,0 +1,8 @@ +use bevy::prelude::*; + +#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)] +pub enum NetworkState { + #[default] + SinglePlayer, + MultiPlayer, +}