use std::net::SocketAddr; use bevy::prelude::*; use uuid::Uuid; use super::{ io::{ Config, InboundPacket, OutboundPacket, handle_network_input, handle_network_output, heartbeat, timeouts, }, peer::{Peer, PeerChangeEvent, PeerMap, handle_peer_change}, queues::{NetworkReceive, NetworkSend}, socket::bind_socket, }; #[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)] pub enum NetworkState { #[default] SinglePlayer, MultiPlayer, } pub struct NetIOPlugin { listen: u16, peer: Option, } impl NetIOPlugin { pub fn new(listen: u16, peer: Option) -> Self { Self { listen, peer } } } impl Plugin for NetIOPlugin { fn build(&self, app: &mut App) { app.init_state::() .add_systems( FixedPreUpdate, (handle_network_input, handle_peer_change) .chain() .run_if(in_state(NetworkState::MultiPlayer)), ) .add_systems( FixedUpdate, (heartbeat, timeouts).run_if(in_state(NetworkState::MultiPlayer)), ) .add_systems( FixedPostUpdate, handle_network_output.run_if(in_state(NetworkState::MultiPlayer)), ) .insert_resource(Config::new()) .add_event::() .add_event::() .add_event::(); match bind_socket(self.listen) { Ok((send, receive)) => { app.insert_state(NetworkState::MultiPlayer) .insert_resource(NetworkSend::new(send)) .insert_resource(NetworkReceive::new(receive)); let mut peer_map = PeerMap::default(); if let Some(socket) = self.peer { let entity = app.world_mut().spawn(Peer::new(socket, Uuid::nil())); peer_map.insert(Uuid::nil(), entity.id()); } app.insert_resource(peer_map); } Err(err) => { warn!("Failed to set up networking: {err}"); } }; } }