aboutsummaryrefslogtreecommitdiffstats
path: root/src/server.rs
blob: 3a7dd40d697c905a891083686c11a51bc952fc4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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<ClientId, Entity>);

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<server::ConnectEvent>,
    mut disconnects: EventReader<server::DisconnectEvent>,
    mut entity_map: ResMut<EntityMap>,
) {
    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<EntityMap>,
    mut input_reader: EventReader<server::InputEvent<Inputs>>,
    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;
                        }
                    }
                    _ => {}
                }
            }
        }
    }
}