rust/hedgewars-server/src/handlers.rs
changeset 15075 e935b1ad23f3
parent 15074 c5a6e8566425
child 15102 80ff12edf5e6
equal deleted inserted replaced
15074:c5a6e8566425 15075:e935b1ad23f3
     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         })
   161         }
   157         }
   162     }
   158     }
   163 }
   159 }
   164 
   160 
   165 fn get_recipients(
   161 fn get_recipients(
   166     server: &HWServer,
   162     server: &HwServer,
   167     client_id: ClientId,
   163     client_id: ClientId,
   168     destination: Destination,
   164     destination: Destination,
   169 ) -> Vec<ClientId> {
   165 ) -> Vec<ClientId> {
   170     match destination {
   166     match destination {
   171         Destination::ToSelf => vec![client_id],
   167         Destination::ToSelf => vec![client_id],
   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 {