1 use super::{ |
1 use super::{ |
2 client::HWClient, |
2 client::HwClient, |
|
3 indexslab::IndexSlab, |
|
4 room::HwRoom, |
3 types::{ClientId, RoomId}, |
5 types::{ClientId, RoomId}, |
4 indexslab::IndexSlab, |
|
5 room::HWRoom, |
|
6 }; |
6 }; |
7 use crate::{ |
7 use crate::{protocol::messages::HwProtocolMessage::Greeting, utils}; |
8 utils, |
|
9 protocol::messages::HWProtocolMessage::Greeting |
|
10 }; |
|
11 |
8 |
12 use bitflags::*; |
9 use bitflags::*; |
13 use log::*; |
10 use log::*; |
14 use slab; |
11 use slab; |
15 use std::{borrow::BorrowMut, iter, num::NonZeroU16}; |
12 use std::{borrow::BorrowMut, iter, num::NonZeroU16}; |
16 |
13 |
17 type Slab<T> = slab::Slab<T>; |
14 type Slab<T> = slab::Slab<T>; |
18 |
15 |
19 pub struct HWAnteClient { |
16 pub struct HwAnteClient { |
20 pub nick: Option<String>, |
17 pub nick: Option<String>, |
21 pub protocol_number: Option<NonZeroU16>, |
18 pub protocol_number: Option<NonZeroU16>, |
22 pub server_salt: String, |
19 pub server_salt: String, |
23 pub is_checker: bool, |
20 pub is_checker: bool, |
24 } |
21 } |
25 |
22 |
26 pub struct HWAnteroom { |
23 pub struct HwAnteroom { |
27 pub clients: IndexSlab<HWAnteClient>, |
24 pub clients: IndexSlab<HwAnteClient>, |
28 } |
25 } |
29 |
26 |
30 impl HWAnteroom { |
27 impl HwAnteroom { |
31 pub fn new(clients_limit: usize) -> Self { |
28 pub fn new(clients_limit: usize) -> Self { |
32 let clients = IndexSlab::with_capacity(clients_limit); |
29 let clients = IndexSlab::with_capacity(clients_limit); |
33 HWAnteroom { clients } |
30 HwAnteroom { clients } |
34 } |
31 } |
35 |
32 |
36 pub fn add_client(&mut self, client_id: ClientId, salt: String) { |
33 pub fn add_client(&mut self, client_id: ClientId, salt: String) { |
37 let client = HWAnteClient { |
34 let client = HwAnteClient { |
38 nick: None, |
35 nick: None, |
39 protocol_number: None, |
36 protocol_number: None, |
40 server_salt: salt, |
37 server_salt: salt, |
41 is_checker: false, |
38 is_checker: false, |
42 }; |
39 }; |
43 self.clients.insert(client_id, client); |
40 self.clients.insert(client_id, client); |
44 } |
41 } |
45 |
42 |
46 pub fn remove_client(&mut self, client_id: ClientId) -> Option<HWAnteClient> { |
43 pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteClient> { |
47 let mut client = self.clients.remove(client_id); |
44 let mut client = self.clients.remove(client_id); |
48 client |
45 client |
49 } |
46 } |
50 } |
47 } |
51 |
48 |
67 pub struct ServerFlags: u8 { |
64 pub struct ServerFlags: u8 { |
68 const REGISTERED_ONLY = 0b0000_1000; |
65 const REGISTERED_ONLY = 0b0000_1000; |
69 } |
66 } |
70 } |
67 } |
71 |
68 |
72 pub struct HWServer { |
69 pub struct HwServer { |
73 pub clients: IndexSlab<HWClient>, |
70 pub clients: IndexSlab<HwClient>, |
74 pub rooms: Slab<HWRoom>, |
71 pub rooms: Slab<HwRoom>, |
75 pub anteroom: HWAnteroom, |
72 pub anteroom: HwAnteroom, |
76 pub latest_protocol: u16, |
73 pub latest_protocol: u16, |
77 pub flags: ServerFlags, |
74 pub flags: ServerFlags, |
78 pub greetings: ServerGreetings, |
75 pub greetings: ServerGreetings, |
79 } |
76 } |
80 |
77 |
81 impl HWServer { |
78 impl HwServer { |
82 pub fn new(clients_limit: usize, rooms_limit: usize) -> Self { |
79 pub fn new(clients_limit: usize, rooms_limit: usize) -> Self { |
83 let rooms = Slab::with_capacity(rooms_limit); |
80 let rooms = Slab::with_capacity(rooms_limit); |
84 let clients = IndexSlab::with_capacity(clients_limit); |
81 let clients = IndexSlab::with_capacity(clients_limit); |
85 Self { |
82 Self { |
86 clients, |
83 clients, |
87 rooms, |
84 rooms, |
88 anteroom: HWAnteroom::new(clients_limit), |
85 anteroom: HwAnteroom::new(clients_limit), |
89 greetings: ServerGreetings::new(), |
86 greetings: ServerGreetings::new(), |
90 latest_protocol: 58, |
87 latest_protocol: 58, |
91 flags: ServerFlags::empty(), |
88 flags: ServerFlags::empty(), |
92 } |
89 } |
93 } |
90 } |
94 |
91 |
95 pub fn add_client(&mut self, client_id: ClientId, data: HWAnteClient) { |
92 pub fn add_client(&mut self, client_id: ClientId, data: HwAnteClient) { |
96 if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) { |
93 if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) { |
97 let mut client = HWClient::new(client_id, protocol.get(), nick); |
94 let mut client = HwClient::new(client_id, protocol.get(), nick); |
98 client.set_is_checker(data.is_checker); |
95 client.set_is_checker(data.is_checker); |
99 self.clients.insert(client_id, client); |
96 self.clients.insert(client_id, client); |
100 } |
97 } |
101 } |
98 } |
102 |
99 |
134 |
131 |
135 pub fn has_room(&self, name: &str) -> bool { |
132 pub fn has_room(&self, name: &str) -> bool { |
136 self.find_room(name).is_some() |
133 self.find_room(name).is_some() |
137 } |
134 } |
138 |
135 |
139 pub fn find_room(&self, name: &str) -> Option<&HWRoom> { |
136 pub fn find_room(&self, name: &str) -> Option<&HwRoom> { |
140 self.rooms |
137 self.rooms |
141 .iter() |
138 .iter() |
142 .find_map(|(_, r)| Some(r).filter(|r| r.name == name)) |
139 .find_map(|(_, r)| Some(r).filter(|r| r.name == name)) |
143 } |
140 } |
144 |
141 |
145 pub fn find_room_mut(&mut self, name: &str) -> Option<&mut HWRoom> { |
142 pub fn find_room_mut(&mut self, name: &str) -> Option<&mut HwRoom> { |
146 self.rooms |
143 self.rooms |
147 .iter_mut() |
144 .iter_mut() |
148 .find_map(|(_, r)| Some(r).filter(|r| r.name == name)) |
145 .find_map(|(_, r)| Some(r).filter(|r| r.name == name)) |
149 } |
146 } |
150 |
147 |
151 pub fn find_client(&self, nick: &str) -> Option<&HWClient> { |
148 pub fn find_client(&self, nick: &str) -> Option<&HwClient> { |
152 self.clients |
149 self.clients |
153 .iter() |
150 .iter() |
154 .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick)) |
151 .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick)) |
155 } |
152 } |
156 |
153 |
157 pub fn find_client_mut(&mut self, nick: &str) -> Option<&mut HWClient> { |
154 pub fn find_client_mut(&mut self, nick: &str) -> Option<&mut HwClient> { |
158 self.clients |
155 self.clients |
159 .iter_mut() |
156 .iter_mut() |
160 .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick)) |
157 .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick)) |
161 } |
158 } |
162 |
159 |
164 self.clients.iter().map(|(id, _)| id) |
161 self.clients.iter().map(|(id, _)| id) |
165 } |
162 } |
166 |
163 |
167 pub fn filter_clients<'a, F>(&'a self, f: F) -> impl Iterator<Item = ClientId> + 'a |
164 pub fn filter_clients<'a, F>(&'a self, f: F) -> impl Iterator<Item = ClientId> + 'a |
168 where |
165 where |
169 F: Fn(&(usize, &HWClient)) -> bool + 'a, |
166 F: Fn(&(usize, &HwClient)) -> bool + 'a, |
170 { |
167 { |
171 self.clients.iter().filter(f).map(|(_, c)| c.id) |
168 self.clients.iter().filter(f).map(|(_, c)| c.id) |
172 } |
169 } |
173 |
170 |
174 pub fn filter_rooms<'a, F>(&'a self, f: F) -> impl Iterator<Item = RoomId> + 'a |
171 pub fn filter_rooms<'a, F>(&'a self, f: F) -> impl Iterator<Item = RoomId> + 'a |
175 where |
172 where |
176 F: Fn(&(usize, &HWRoom)) -> bool + 'a, |
173 F: Fn(&(usize, &HwRoom)) -> bool + 'a, |
177 { |
174 { |
178 self.rooms.iter().filter(f).map(|(_, c)| c.id) |
175 self.rooms.iter().filter(f).map(|(_, c)| c.id) |
179 } |
176 } |
180 |
177 |
181 pub fn collect_clients<F>(&self, f: F) -> Vec<ClientId> |
178 pub fn collect_clients<F>(&self, f: F) -> Vec<ClientId> |
182 where |
179 where |
183 F: Fn(&(usize, &HWClient)) -> bool, |
180 F: Fn(&(usize, &HwClient)) -> bool, |
184 { |
181 { |
185 self.filter_clients(f).collect() |
182 self.filter_clients(f).collect() |
186 } |
183 } |
187 |
184 |
188 pub fn collect_nicks<F>(&self, f: F) -> Vec<String> |
185 pub fn collect_nicks<F>(&self, f: F) -> Vec<String> |
189 where |
186 where |
190 F: Fn(&(usize, &HWClient)) -> bool, |
187 F: Fn(&(usize, &HwClient)) -> bool, |
191 { |
188 { |
192 self.clients |
189 self.clients |
193 .iter() |
190 .iter() |
194 .filter(f) |
191 .filter(f) |
195 .map(|(_, c)| c.nick.clone()) |
192 .map(|(_, c)| c.nick.clone()) |
224 pub fn set_is_registered_only(&mut self, value: bool) { |
221 pub fn set_is_registered_only(&mut self, value: bool) { |
225 self.flags.set(ServerFlags::REGISTERED_ONLY, value) |
222 self.flags.set(ServerFlags::REGISTERED_ONLY, value) |
226 } |
223 } |
227 } |
224 } |
228 |
225 |
229 fn allocate_room(rooms: &mut Slab<HWRoom>) -> &mut HWRoom { |
226 fn allocate_room(rooms: &mut Slab<HwRoom>) -> &mut HwRoom { |
230 let entry = rooms.vacant_entry(); |
227 let entry = rooms.vacant_entry(); |
231 let room = HWRoom::new(entry.key()); |
228 let room = HwRoom::new(entry.key()); |
232 entry.insert(room) |
229 entry.insert(room) |
233 } |
230 } |
234 |
231 |
235 fn create_room( |
232 fn create_room( |
236 client: &mut HWClient, |
233 client: &mut HwClient, |
237 rooms: &mut Slab<HWRoom>, |
234 rooms: &mut Slab<HwRoom>, |
238 name: String, |
235 name: String, |
239 password: Option<String>, |
236 password: Option<String>, |
240 ) -> RoomId { |
237 ) -> RoomId { |
241 let room = allocate_room(rooms); |
238 let room = allocate_room(rooms); |
242 |
239 |