aboutsummaryrefslogtreecommitdiff
path: root/examples/chat_server/main.rs
blob: 81cd209768cdaa591c189e7ed626d0f231f9c747 (plain) (blame)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use std::collections::HashMap;

use bevy::{app::ScheduleRunnerPlugin, log::LogPlugin, prelude::*};
use bevy_quinnet::{
    server::{QuinnetServerPlugin, Server, ServerConfigurationData},
    ClientId,
};

use chat_protocol::{ClientMessage, ServerMessage};

#[path = "../chat_protocol/lib.rs"] // Because we can't have a shared lib between Cargo examples
mod chat_protocol;

#[derive(Debug, Clone, Default)]
struct Users {
    names: HashMap<ClientId, String>,
}

fn handle_client_messages(mut server: ResMut<Server>, mut users: ResMut<Users>) {
    while let Ok(Some(message)) = server.receive_message::<ClientMessage>() {
        let client_id = message.1;
        match message.0 {
            ClientMessage::Join { name } => {
                if users.names.contains_key(&client_id) {
                    warn!(
                        "Received a Join from an already connected client: {}",
                        client_id
                    )
                } else {
                    info!("{} connected", name);
                    users.names.insert(client_id, name.clone());
                    // Initialize this client with existing state
                    server
                        .send_message(
                            client_id,
                            ServerMessage::InitClient {
                                client_id: client_id,
                                usernames: users.names.clone(),
                            },
                        )
                        .unwrap();
                    // Broadcast the connection event
                    server
                        .send_group_message(
                            users.names.keys().into_iter(),
                            ServerMessage::ClientConnected {
                                client_id: client_id,
                                username: name,
                            },
                        )
                        .unwrap();
                }
            }
            ClientMessage::Disconnect {} => {
                if let Some(username) = users.names.remove(&client_id) {
                    server.disconnect_client(client_id);
                    // Broadcast its deconnection
                    server
                        .send_group_message(
                            users.names.keys().into_iter(),
                            ServerMessage::ClientDisconnected {
                                client_id: client_id,
                            },
                        )
                        .unwrap();
                    info!("{} disconnected", username);
                } else {
                    warn!(
                        "Received a Disconnect from an unknown or disconnected client: {}",
                        client_id
                    )
                }
            }
            ClientMessage::ChatMessage { message } => {
                info!(
                    "Chat message | {:?}: {}",
                    users.names.get(&client_id),
                    message
                );
                server
                    .send_group_message(
                        users.names.keys().into_iter(),
                        ServerMessage::ChatMessage {
                            client_id: client_id,
                            message: message,
                        },
                    )
                    .unwrap();
            }
        }
    }
}

fn main() {
    App::new()
        .add_plugin(ScheduleRunnerPlugin::default())
        .add_plugin(LogPlugin::default())
        .add_plugin(QuinnetServerPlugin::default())
        .insert_resource(ServerConfigurationData::new(
            "127.0.0.1".to_string(),
            6000,
            "0.0.0.0".to_string(),
        ))
        .insert_resource(Users::default())
        .add_system(handle_client_messages)
        .run();
}