use crate::protocol::*; use crate::server::network::*; use crate::shared::imperative::*; use crate::shared::*; use bevy::prelude::*; use bevy::utils::HashMap; use lightyear::prelude::*; use rand::Rng; mod network; #[derive(Resource, Default)] struct EntityMap(HashMap); pub fn main(transport: TransportConfig) { App::new() .add_plugins(MinimalPlugins) .add_plugins(ServerPlugin { transport }) .run(); } struct ServerPlugin { pub transport: TransportConfig, } impl Plugin for ServerPlugin { fn build(&self, app: &mut App) { app.insert_resource(EntityMap::default()) .add_plugins(NetworkPlugin { transport: self.transport.clone(), }) .add_systems(Update, connections) .add_systems(FixedUpdate, player_input) .add_systems(Update, imperative); } } fn connections( mut commands: Commands, mut connects: EventReader, mut disconnects: EventReader, mut entity_map: ResMut, ) { let mut rng = rand::thread_rng(); for connection in connects.read() { let client_id = connection.context(); info!("connected: {:?}", client_id); let position = Vec2::new( 50. * rng.gen_range(-2..=2) as f32, 50. * rng.gen_range(-2..=2) as f32, ); let color = Color::hsl(360. * rng.gen_range(0..=15) as f32 / 16., 0.95, 0.7); let entity = commands.spawn(PlayerBundle::new(*client_id, position, color)); entity_map.0.insert(*client_id, entity.id()); } for connection in disconnects.read() { let client_id = connection.context(); info!("disconnected: {:?}", client_id); if let Some(entity_id) = entity_map.0.remove(client_id) { commands.entity(entity_id).despawn(); } } } fn player_input( entity_map: Res, mut input_reader: EventReader>, mut imperatives: Query<&mut Imperative>, ) { for input in input_reader.read() { let client_id = input.context(); if let Some(input) = input.input() { if let Some(entity_id) = entity_map.0.get(client_id) { match input { Inputs::Imperative(new_imperative) => { if let Ok(mut imperative) = imperatives.get_mut(*entity_id) { *imperative = *new_imperative; } } _ => {} } } } } } const MOVEMENT_SPEED: f32 = 80.; fn imperative(mut players: Query<(&mut Imperative, &mut PlayerPosition)>, time: Res