1 use mio; |
1 use mio; |
2 use std::{collections::HashMap, io, io::Write}; |
2 use std::{collections::HashMap, io, io::Write}; |
3 |
3 |
4 use self::{ |
4 use self::{ |
5 actions::{Destination, DestinationGroup, PendingMessage}, |
5 actions::{Destination, DestinationGroup, PendingMessage}, |
6 inanteroom::LoginResult |
6 inanteroom::LoginResult, |
7 }; |
7 }; |
8 use crate::{ |
8 use crate::{ |
9 core::{ |
9 core::{ |
10 server::HWServer, |
10 room::RoomSave, |
11 types::{ClientId, Replay, RoomId, GameCfg, TeamInfo}, |
11 server::HwServer, |
12 room::RoomSave |
12 types::{ClientId, GameCfg, Replay, RoomId, TeamInfo}, |
13 }, |
13 }, |
14 protocol::messages::{ |
14 protocol::messages::{ |
15 server_chat, |
15 global_chat, server_chat, HwProtocolMessage, HwProtocolMessage::EngineMessage, |
16 HWProtocolMessage, |
16 HwServerMessage, HwServerMessage::*, |
17 HWServerMessage, |
|
18 HWServerMessage::*, |
|
19 global_chat, |
|
20 HWProtocolMessage::EngineMessage |
|
21 }, |
17 }, |
22 utils, |
18 utils, |
23 }; |
19 }; |
24 use base64::encode; |
20 use base64::encode; |
25 use log::*; |
21 use log::*; |
26 use rand::{thread_rng, RngCore}; |
22 use rand::{thread_rng, RngCore}; |
27 |
23 |
28 mod actions; |
24 mod actions; |
29 mod checker; |
25 mod checker; |
30 mod common; |
26 mod common; |
|
27 mod inanteroom; |
|
28 mod inlobby; |
31 mod inroom; |
29 mod inroom; |
32 mod inlobby; |
|
33 mod inanteroom; |
|
34 |
30 |
35 use std::fmt::{Formatter, LowerHex}; |
31 use std::fmt::{Formatter, LowerHex}; |
36 |
32 |
37 #[derive(PartialEq)] |
33 #[derive(PartialEq)] |
38 pub struct Sha1Digest([u8; 20]); |
34 pub struct Sha1Digest([u8; 20]); |
130 self.io_tasks.push(task) |
126 self.io_tasks.push(task) |
131 } |
127 } |
132 |
128 |
133 pub fn extract_messages<'a, 'b: 'a>( |
129 pub fn extract_messages<'a, 'b: 'a>( |
134 &'b mut self, |
130 &'b mut self, |
135 server: &'a HWServer, |
131 server: &'a HwServer, |
136 ) -> impl Iterator<Item = (Vec<ClientId>, HWServerMessage)> + 'a { |
132 ) -> impl Iterator<Item = (Vec<ClientId>, HwServerMessage)> + 'a { |
137 let client_id = self.client_id; |
133 let client_id = self.client_id; |
138 self.messages.drain(..).map(move |m| { |
134 self.messages.drain(..).map(move |m| { |
139 let ids = get_recipients(server, client_id, m.destination); |
135 let ids = get_recipients(server, client_id, m.destination); |
140 (ids, m.message) |
136 (ids, m.message) |
141 }) |
137 }) |
189 } |
185 } |
190 } |
186 } |
191 } |
187 } |
192 |
188 |
193 pub fn handle( |
189 pub fn handle( |
194 server: &mut HWServer, |
190 server: &mut HwServer, |
195 client_id: ClientId, |
191 client_id: ClientId, |
196 response: &mut Response, |
192 response: &mut Response, |
197 message: HWProtocolMessage, |
193 message: HwProtocolMessage, |
198 ) { |
194 ) { |
199 match message { |
195 match message { |
200 HWProtocolMessage::Ping => response.add(Pong.send_self()), |
196 HwProtocolMessage::Ping => response.add(Pong.send_self()), |
201 _ => { |
197 _ => { |
202 if server.anteroom.clients.contains(client_id) { |
198 if server.anteroom.clients.contains(client_id) { |
203 match inanteroom::handle(server, client_id, response, message) { |
199 match inanteroom::handle(server, client_id, response, message) { |
204 LoginResult::Unchanged => (), |
200 LoginResult::Unchanged => (), |
205 LoginResult::Complete => { |
201 LoginResult::Complete => { |
213 response.remove_client(client_id); |
209 response.remove_client(client_id); |
214 } |
210 } |
215 } |
211 } |
216 } else if server.clients.contains(client_id) { |
212 } else if server.clients.contains(client_id) { |
217 match message { |
213 match message { |
218 HWProtocolMessage::Quit(Some(msg)) => { |
214 HwProtocolMessage::Quit(Some(msg)) => { |
219 common::remove_client(server, response, "User quit: ".to_string() + &msg); |
215 common::remove_client(server, response, "User quit: ".to_string() + &msg); |
220 } |
216 } |
221 HWProtocolMessage::Quit(None) => { |
217 HwProtocolMessage::Quit(None) => { |
222 common::remove_client(server, response, "User quit".to_string()); |
218 common::remove_client(server, response, "User quit".to_string()); |
223 } |
219 } |
224 HWProtocolMessage::Info(nick) => { |
220 HwProtocolMessage::Info(nick) => { |
225 if let Some(client) = server.find_client(&nick) { |
221 if let Some(client) = server.find_client(&nick) { |
226 let admin_sign = if client.is_admin() { "@" } else { "" }; |
222 let admin_sign = if client.is_admin() { "@" } else { "" }; |
227 let master_sign = if client.is_master() { "+" } else { "" }; |
223 let master_sign = if client.is_master() { "+" } else { "" }; |
228 let room_info = match client.room_id { |
224 let room_info = match client.room_id { |
229 Some(room_id) => { |
225 Some(room_id) => { |
251 } else { |
247 } else { |
252 response |
248 response |
253 .add(server_chat("Player is not online.".to_string()).send_self()) |
249 .add(server_chat("Player is not online.".to_string()).send_self()) |
254 } |
250 } |
255 } |
251 } |
256 HWProtocolMessage::ToggleServerRegisteredOnly => { |
252 HwProtocolMessage::ToggleServerRegisteredOnly => { |
257 if !server.clients[client_id].is_admin() { |
253 if !server.clients[client_id].is_admin() { |
258 response.add(Warning("Access denied.".to_string()).send_self()); |
254 response.add(Warning("Access denied.".to_string()).send_self()); |
259 } else { |
255 } else { |
260 server.set_is_registered_only(server.is_registered_only()); |
256 server.set_is_registered_only(server.is_registered_only()); |
261 let msg = if server.is_registered_only() { |
257 let msg = if server.is_registered_only() { |
264 "This server now allows unregistered players to join." |
260 "This server now allows unregistered players to join." |
265 }; |
261 }; |
266 response.add(server_chat(msg.to_string()).send_all()); |
262 response.add(server_chat(msg.to_string()).send_all()); |
267 } |
263 } |
268 } |
264 } |
269 HWProtocolMessage::Global(msg) => { |
265 HwProtocolMessage::Global(msg) => { |
270 if !server.clients[client_id].is_admin() { |
266 if !server.clients[client_id].is_admin() { |
271 response.add(Warning("Access denied.".to_string()).send_self()); |
267 response.add(Warning("Access denied.".to_string()).send_self()); |
272 } else { |
268 } else { |
273 response.add(global_chat(msg).send_all()) |
269 response.add(global_chat(msg).send_all()) |
274 } |
270 } |
275 } |
271 } |
276 HWProtocolMessage::SuperPower => { |
272 HwProtocolMessage::SuperPower => { |
277 if !server.clients[client_id].is_admin() { |
273 if !server.clients[client_id].is_admin() { |
278 response.add(Warning("Access denied.".to_string()).send_self()); |
274 response.add(Warning("Access denied.".to_string()).send_self()); |
279 } else { |
275 } else { |
280 server.clients[client_id].set_has_super_power(true); |
276 server.clients[client_id].set_has_super_power(true); |
281 response |
277 response |
282 .add(server_chat("Super power activated.".to_string()).send_self()) |
278 .add(server_chat("Super power activated.".to_string()).send_self()) |
283 } |
279 } |
284 } |
280 } |
285 HWProtocolMessage::Watch(id) => { |
281 HwProtocolMessage::Watch(id) => { |
286 #[cfg(feature = "official-server")] |
282 #[cfg(feature = "official-server")] |
287 { |
283 { |
288 response.request_io(IoTask::GetReplay { id }) |
284 response.request_io(IoTask::GetReplay { id }) |
289 } |
285 } |
290 |
286 |
306 } |
302 } |
307 } |
303 } |
308 } |
304 } |
309 } |
305 } |
310 |
306 |
311 pub fn handle_client_accept(server: &mut HWServer, client_id: ClientId, response: &mut Response) { |
307 pub fn handle_client_accept(server: &mut HwServer, client_id: ClientId, response: &mut Response) { |
312 let mut salt = [0u8; 18]; |
308 let mut salt = [0u8; 18]; |
313 thread_rng().fill_bytes(&mut salt); |
309 thread_rng().fill_bytes(&mut salt); |
314 |
310 |
315 server.anteroom.add_client(client_id, encode(&salt)); |
311 server.anteroom.add_client(client_id, encode(&salt)); |
316 |
312 |
317 response.add(HWServerMessage::Connected(utils::SERVER_VERSION).send_self()); |
313 response.add(HwServerMessage::Connected(utils::SERVER_VERSION).send_self()); |
318 } |
314 } |
319 |
315 |
320 pub fn handle_client_loss(server: &mut HWServer, client_id: ClientId, response: &mut Response) { |
316 pub fn handle_client_loss(server: &mut HwServer, client_id: ClientId, response: &mut Response) { |
321 if server.anteroom.remove_client(client_id).is_none() { |
317 if server.anteroom.remove_client(client_id).is_none() { |
322 common::remove_client(server, response, "Connection reset".to_string()); |
318 common::remove_client(server, response, "Connection reset".to_string()); |
323 } |
319 } |
324 } |
320 } |
325 |
321 |
326 pub fn handle_io_result( |
322 pub fn handle_io_result( |
327 server: &mut HWServer, |
323 server: &mut HwServer, |
328 client_id: ClientId, |
324 client_id: ClientId, |
329 response: &mut Response, |
325 response: &mut Response, |
330 io_result: IoResult, |
326 io_result: IoResult, |
331 ) { |
327 ) { |
332 match io_result { |
328 match io_result { |