use crate::protocol::*; use crate::server::network::*; 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); } } 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 positions: Query<&mut PlayerPosition>, ) { 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::Teleport(new_position) => { if let Ok(mut position) = positions.get_mut(*entity_id) { position.0 = *new_position; } } _ => {} } } } } }