use bevy::utils::tracing; use bevy::{ecs::event::ManualEventReader, prelude::*}; use bevy_twite::{twite::frame::MessageType, ServerEvent, TwiteServerConfig, TwiteServerPlugin}; use component::*; use packet::*; pub mod component; pub mod packet; fn main() { let subscriber = tracing_subscriber::FmtSubscriber::new(); tracing::subscriber::set_global_default(subscriber).unwrap(); info!( "StarKingdoms server v{} starting up", env!("CARGO_PKG_VERSION") ); App::new() .insert_resource(TwiteServerConfig { port: 3000 }) .add_plugins(MinimalPlugins) .add_plugins(TwiteServerPlugin) .add_systems(Startup, spawn_planets) .add_systems(Update, on_connection) .add_systems(FixedUpdate, on_position_change) .run(); info!("Goodbye!"); } fn spawn_planets(mut commands: Commands) { info!("Spawning planets"); let earth_pos = Transform::from_xyz(0.0, 0.0, 0.0); commands.spawn(PlanetBundle { planet_type: PlanetType::Earth, transform: TransformBundle::from(earth_pos), }); } fn on_connection( mut commands: Commands, planet_query: Query<(Entity, &PlanetType, &Transform)>, mut reader: Local>, mut events: ResMut>, ) { let mut packets = Vec::new(); for ev in reader.read(&events) { info!("{:?}", ev); if let ServerEvent::Connection(addr) = ev { info!("client connected"); let _id = commands .spawn(PlayerBundle { part: PartBundle { part_type: PartType::Hearty, transform: TransformBundle::from(Transform::from_xyz(0.0, 0.0, 0.0)), }, addr: Player(*addr), }) .id() .index(); let mut planets = Vec::new(); for (entity, planet_type, transform) in planet_query.iter() { planets.push((entity.index(), Planet { planet_type: *planet_type, transform: proto_transform!(transform) })); } let packet = Packet::PlanetPositions { planets }; let buf = serde_json::to_vec(&packet).unwrap(); packets.push(ServerEvent::Send(*addr, MessageType::Text, buf)); } } for packet in packets { events.send(packet); } } fn on_position_change( mut commands: Commands, part_query: Query<(Entity, &PartType, &Transform), (With, Changed)>, planet_query: Query<(Entity, &PlanetType, &Transform), Changed>, mut packet_send: EventWriter, ) { let mut updated_parts = Vec::new(); for (entity, part_type, transform) in part_query.iter() { let id = commands.entity(entity).id().index(); updated_parts.push((id, Part { part_type: *part_type, transform: proto_transform!(transform), })); } if !updated_parts.is_empty() { let packet = Packet::PartPositions { parts: updated_parts }; let buf = serde_json::to_vec(&packet).unwrap(); packet_send.send(ServerEvent::Broadcast(MessageType::Text, buf)); } let mut planets = Vec::new(); for (entity, planet_type, transform) in planet_query.iter() { let id = commands.entity(entity).id().index(); planets.push((id, Planet { planet_type: *planet_type, transform: proto_transform!(transform) })); } if !planets.is_empty() { let packet = Packet::PlanetPositions { planets }; let buf = serde_json::to_vec(&packet).unwrap(); packet_send.send(ServerEvent::Broadcast(MessageType::Text, buf)); } }