diff --git a/src/game/net.rs b/src/game/net.rs index 524b376..8e43e3f 100644 --- a/src/game/net.rs +++ b/src/game/net.rs @@ -2,24 +2,16 @@ use bevy::prelude::*; use crate::net::prelude::*; -use super::seed::Seed; - -pub fn handle_new_peer( - seed: Option>, - new_peers: Query<&Peer, Added>, - mut outbound: EventWriter, -) { - if let Some(seed) = seed { - for peer in new_peers { - outbound.write(OutboundPacket(Packet::new((*seed).into(), peer.uuid))); - } +pub fn handle_new_peer(new_peers: Query<&Peer, Added>) { + for peer in new_peers { + info!("Peer {} was added", peer.id); } } pub fn handle_deleted_peer(mut old_peers: RemovedComponents, peers: Query<&Peer>) -> Result { for entity in old_peers.read() { if let Ok(peer) = peers.get(entity) { - info!("Peer {} was removed", peer.uuid); + info!("Peer {} was removed", peer.id); } else { info!("Peer {} was removed", entity); } @@ -27,12 +19,8 @@ pub fn handle_deleted_peer(mut old_peers: RemovedComponents, peers: Query< Ok(()) } -pub fn handle_incoming_packets(mut packets: EventReader, mut commands: Commands) { +pub fn handle_incoming_packets(mut packets: EventReader) { for packet in packets.read() { - if let Ok(seed) = packet.0.message.clone().try_into() { - commands.insert_resource::(seed); - } else { - info!("Packet not seed: {:?}", packet.0.message); - } + info!("Packet received: {:?}", packet.0.message); } } diff --git a/src/game/plugin.rs b/src/game/plugin.rs index 6943b7b..d879c20 100644 --- a/src/game/plugin.rs +++ b/src/game/plugin.rs @@ -91,15 +91,17 @@ impl Plugin for GamePlugin { ), ); + Seed::register(app); + match self.source { DataSource::Address(peer) => { info!("Will retrieve seed from peer => {peer}"); } DataSource::Seed(seed) => { - app.insert_resource(seed); + app.world_mut().spawn(seed); } DataSource::None => { - app.insert_resource(Seed::random()); + app.world_mut().spawn(Seed::random()); } }; } diff --git a/src/game/runtime.rs b/src/game/runtime.rs index ab393ad..fa828f0 100644 --- a/src/game/runtime.rs +++ b/src/game/runtime.rs @@ -78,6 +78,6 @@ pub fn zoom_camera( MouseScrollUnit::Line => 0.1, MouseScrollUnit::Pixel => 0.001, }; - projection.scale = (projection.scale - scroll.delta.y * scroll_type_multiplier).clamp(0.1, 2.5); + projection.scale = (projection.scale - scroll.delta.y * scroll_type_multiplier).clamp(0.1, 4.0); Ok(()) } diff --git a/src/game/seed.rs b/src/game/seed.rs index 12d6a07..085c10c 100644 --- a/src/game/seed.rs +++ b/src/game/seed.rs @@ -7,7 +7,7 @@ use bevy::prelude::*; use rand::random; /// Value with which to initialize the PRNG -#[derive(Resource, Debug, Clone, Copy)] +#[derive(Clone, Component, Copy, Debug)] pub struct Seed(u64); impl Seed { @@ -62,7 +62,6 @@ impl TryFrom> for Seed { type Error = TryFromSliceError; fn try_from(value: Vec) -> Result { - let bytes: [u8; 8] = value.as_slice().try_into()?; - Ok(bytes.into()) + Ok(TryInto::<[u8; 8]>::try_into(value.as_slice())?.into()) } } diff --git a/src/game/setup.rs b/src/game/setup.rs index eb4585c..464b9db 100644 --- a/src/game/setup.rs +++ b/src/game/setup.rs @@ -23,7 +23,7 @@ const BALL_COUNT: u8 = 32; const BALL_SIZES: Range = 10.0..25.0; const DIMENSION_SIZES: Range = 500.0..2000.0; -pub fn check_for_seed(seed: Option>, mut next_state: ResMut>) { +pub fn check_for_seed(seed: Option>, mut next_state: ResMut>) { if seed.is_some() { next_state.set(AppState::InGame); } @@ -34,8 +34,8 @@ pub fn check_for_seed(seed: Option>, mut next_state: ResMut) { - let mut rng = WyRand::from_seed((*seed).into()); +pub fn setup_from_seed(mut commands: Commands, seed: Single<&Seed>) { + let mut rng = WyRand::from_seed((**seed).into()); commands.insert_resource(PlayableArea( rng.random_range(DIMENSION_SIZES), rng.random_range(DIMENSION_SIZES), diff --git a/src/game/ui.rs b/src/game/ui.rs index 4abd6d1..391a39f 100644 --- a/src/game/ui.rs +++ b/src/game/ui.rs @@ -21,13 +21,10 @@ pub fn setup_seed_ui(mut commands: Commands) { .with_child((TextSpan::new(""), SeedUI)); } -pub fn update_seed_ui(seed: Option>, text: Query<&mut TextSpan, With>) { +pub fn update_seed_ui(seed: Option>, text: Query<&mut TextSpan, With>) { if let Some(value) = seed { - if value.is_changed() { - for mut span in text { - let number: u64 = (*value).into(); - **span = format!("{}", number); - } + for mut span in text { + **span = format!("{}", u64::from(**value)); } } } @@ -93,8 +90,8 @@ pub fn update_peer_ui_timings( if let Ok((peer, recv, send)) = peers.get(id.0) { **row = format!( "{} {:.2} {:.2}", - peer.uuid, - (time.elapsed() - recv.time().unwrap_or(default())).as_secs_f64(), + peer.id, + (time.elapsed() - recv.time()).as_secs_f64(), (time.elapsed() - send.time()).as_secs_f64() ) } diff --git a/src/net/distribution.rs b/src/net/distribution.rs new file mode 100644 index 0000000..161ea1a --- /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.id, + ))); + } + } +} + +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/io.rs b/src/net/io.rs index 7dcceca..25774b6 100644 --- a/src/net/io.rs +++ b/src/net/io.rs @@ -3,16 +3,18 @@ use std::time::Duration; use bevy::prelude::*; use uuid::Uuid; +use crate::net::peer::PotentialPeer; + use super::{ packet::{InboundPacket, OutboundPacket, Packet}, - peer::{Peer, PeerChangeEvent, PeerMap, PeerReceiveTiming, PeerSendTiming}, + peer::{Peer, PeerChangeEvent, PeerData, PeerMap, PeerReceiveTiming, PeerSendTiming}, queues::{NetworkReceive, NetworkSend}, }; pub fn handle_network_input( from_socket: Res, peer_map: Res, - mut peers: Query<(&Peer, &mut PeerReceiveTiming)>, + mut peers: Query<(&PeerData, &mut PeerReceiveTiming)>, mut to_app: EventWriter, time: Res