2 actions, |
2 actions, |
3 actions::{Destination, PendingMessage}, |
3 actions::{Destination, PendingMessage}, |
4 client::HWClient, |
4 client::HWClient, |
5 coretypes::{ClientId, RoomId}, |
5 coretypes::{ClientId, RoomId}, |
6 handlers, |
6 handlers, |
|
7 indexslab::IndexSlab, |
7 io::HWServerIO, |
8 io::HWServerIO, |
8 room::HWRoom, |
9 room::HWRoom, |
9 }; |
10 }; |
10 use crate::protocol::messages::*; |
11 use crate::{protocol::messages::*, utils}; |
11 use crate::utils; |
12 |
12 use base64::encode; |
|
13 use log::*; |
13 use log::*; |
14 use rand::{thread_rng, RngCore}; |
|
15 use slab; |
14 use slab; |
16 use std::borrow::BorrowMut; |
15 use std::{borrow::BorrowMut, iter, num::NonZeroU16}; |
17 |
16 |
18 type Slab<T> = slab::Slab<T>; |
17 type Slab<T> = slab::Slab<T>; |
19 |
18 |
|
19 pub struct HWAnteClient { |
|
20 pub nick: Option<String>, |
|
21 pub protocol_number: Option<NonZeroU16>, |
|
22 pub server_salt: String, |
|
23 pub web_password: String, |
|
24 } |
|
25 |
|
26 pub struct HWAnteroom { |
|
27 pub clients: IndexSlab<HWAnteClient>, |
|
28 } |
|
29 |
|
30 impl HWAnteroom { |
|
31 pub fn new(clients_limit: usize) -> Self { |
|
32 let clients = IndexSlab::with_capacity(clients_limit); |
|
33 HWAnteroom { clients } |
|
34 } |
|
35 |
|
36 pub fn add_client(&mut self, client_id: ClientId, salt: String) { |
|
37 let client = HWAnteClient { |
|
38 nick: None, |
|
39 protocol_number: None, |
|
40 server_salt: salt, |
|
41 web_password: "".to_string(), |
|
42 }; |
|
43 self.clients.insert(client_id, client); |
|
44 } |
|
45 |
|
46 pub fn remove_client(&mut self, client_id: ClientId) -> Option<HWAnteClient> { |
|
47 let mut client = self.clients.remove(client_id); |
|
48 if let Some(ref mut client) = client { |
|
49 client |
|
50 .web_password |
|
51 .replace_range(.., "🦔🦔🦔🦔🦔🦔🦔🦔"); |
|
52 } |
|
53 client |
|
54 } |
|
55 } |
|
56 |
20 pub struct HWServer { |
57 pub struct HWServer { |
21 pub clients: Slab<HWClient>, |
58 pub clients: IndexSlab<HWClient>, |
22 pub rooms: Slab<HWRoom>, |
59 pub rooms: Slab<HWRoom>, |
23 pub lobby_id: RoomId, |
60 pub lobby_id: RoomId, |
24 pub output: Vec<(Vec<ClientId>, HWServerMessage)>, |
61 pub output: Vec<(Vec<ClientId>, HWServerMessage)>, |
25 pub removed_clients: Vec<ClientId>, |
62 pub removed_clients: Vec<ClientId>, |
26 pub io: Box<dyn HWServerIO>, |
63 pub io: Box<dyn HWServerIO>, |
|
64 pub anteroom: HWAnteroom, |
27 } |
65 } |
28 |
66 |
29 impl HWServer { |
67 impl HWServer { |
30 pub fn new(clients_limit: usize, rooms_limit: usize, io: Box<dyn HWServerIO>) -> HWServer { |
68 pub fn new(clients_limit: usize, rooms_limit: usize, io: Box<dyn HWServerIO>) -> Self { |
31 let rooms = Slab::with_capacity(rooms_limit); |
69 let rooms = Slab::with_capacity(rooms_limit); |
32 let clients = Slab::with_capacity(clients_limit); |
70 let clients = IndexSlab::with_capacity(clients_limit); |
33 let mut server = HWServer { |
71 let mut server = Self { |
34 clients, |
72 clients, |
35 rooms, |
73 rooms, |
36 lobby_id: 0, |
74 lobby_id: 0, |
37 output: vec![], |
75 output: vec![], |
38 removed_clients: vec![], |
76 removed_clients: vec![], |
39 io, |
77 io, |
|
78 anteroom: HWAnteroom::new(clients_limit), |
40 }; |
79 }; |
41 server.lobby_id = server.add_room().id; |
80 server.lobby_id = server.add_room().id; |
42 server |
81 server |
43 } |
82 } |
44 |
83 |
45 pub fn add_client(&mut self) -> ClientId { |
84 pub fn add_client(&mut self, client_id: ClientId, data: HWAnteClient) { |
46 let key: ClientId; |
85 if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) { |
47 { |
86 let client = HWClient::new(client_id, protocol.get(), nick); |
48 let entry = self.clients.vacant_entry(); |
87 self.clients.insert(client_id, client); |
49 key = entry.key(); |
88 } |
50 let mut salt = [0u8; 18]; |
|
51 thread_rng().fill_bytes(&mut salt); |
|
52 |
|
53 let client = HWClient::new(entry.key(), encode(&salt)); |
|
54 entry.insert(client); |
|
55 } |
|
56 self.send( |
|
57 key, |
|
58 &Destination::ToSelf, |
|
59 HWServerMessage::Connected(utils::PROTOCOL_VERSION), |
|
60 ); |
|
61 key |
|
62 } |
89 } |
63 |
90 |
64 pub fn remove_client(&mut self, client_id: ClientId) { |
91 pub fn remove_client(&mut self, client_id: ClientId) { |
65 self.removed_clients.push(client_id); |
92 self.removed_clients.push(client_id); |
66 if self.clients.contains(client_id) { |
93 if self.clients.contains(client_id) { |
90 #[inline] |
117 #[inline] |
91 pub fn move_to_room(&mut self, client_id: ClientId, room_id: RoomId) { |
118 pub fn move_to_room(&mut self, client_id: ClientId, room_id: RoomId) { |
92 move_to_room(&mut self.clients[client_id], &mut self.rooms[room_id]) |
119 move_to_room(&mut self.clients[client_id], &mut self.rooms[room_id]) |
93 } |
120 } |
94 |
121 |
95 pub fn send( |
|
96 &mut self, |
|
97 client_id: ClientId, |
|
98 destination: &Destination, |
|
99 message: HWServerMessage, |
|
100 ) { |
|
101 |
|
102 } |
|
103 |
|
104 pub fn send_msg(&mut self, client_id: ClientId, message: PendingMessage) { |
|
105 self.send(client_id, &message.destination, message.message) |
|
106 } |
|
107 |
|
108 pub fn lobby(&self) -> &HWRoom { |
122 pub fn lobby(&self) -> &HWRoom { |
109 &self.rooms[self.lobby_id] |
123 &self.rooms[self.lobby_id] |
110 } |
124 } |
111 |
125 |
112 pub fn has_room(&self, name: &str) -> bool { |
126 pub fn has_room(&self, name: &str) -> bool { |