rust/hedgewars-server/src/handlers/inlobby.rs
changeset 15074 c5a6e8566425
parent 14797 ce2268ae261f
child 15075 e935b1ad23f3
equal deleted inserted replaced
15073:7732013ce64c 15074:c5a6e8566425
       
     1 use mio;
       
     2 
       
     3 use super::common::rnd_reply;
       
     4 use crate::{
       
     5     protocol::messages::{
       
     6         add_flags, remove_flags, server_chat, HWProtocolMessage, HWServerMessage::*,
       
     7         ProtocolFlags as Flags,
       
     8     },
       
     9     core::{
       
    10         client::HWClient,
       
    11         server::HWServer,
       
    12         types::{ClientId, ServerVar},
       
    13     },
       
    14     utils::is_name_illegal,
       
    15 };
       
    16 use log::*;
       
    17 use std::{collections::HashSet, convert::identity};
       
    18 
       
    19 pub fn handle(
       
    20     server: &mut HWServer,
       
    21     client_id: ClientId,
       
    22     response: &mut super::Response,
       
    23     message: HWProtocolMessage,
       
    24 ) {
       
    25     use crate::protocol::messages::HWProtocolMessage::*;
       
    26     match message {
       
    27         CreateRoom(name, password) => {
       
    28             if is_name_illegal(&name) {
       
    29                 response.add(Warning("Illegal room name! A room name must be between 1-40 characters long, must not have a trailing or leading space and must not have any of these characters: $()*+?[]^{|}".to_string()).send_self());
       
    30             } else if server.has_room(&name) {
       
    31                 response.add(
       
    32                     Warning("A room with the same name already exists.".to_string()).send_self(),
       
    33                 );
       
    34             } else {
       
    35                 let flags_msg = ClientFlags(
       
    36                     add_flags(&[Flags::RoomMaster, Flags::Ready]),
       
    37                     vec![server.clients[client_id].nick.clone()],
       
    38                 );
       
    39 
       
    40                 let room_id = server.create_room(client_id, name, password);
       
    41                 let room = &server.rooms[room_id];
       
    42                 let client = &server.clients[client_id];
       
    43 
       
    44                 response.add(
       
    45                     RoomAdd(room.info(Some(&client)))
       
    46                         .send_all()
       
    47                         .with_protocol(room.protocol_number),
       
    48                 );
       
    49                 response.add(RoomJoined(vec![client.nick.clone()]).send_self());
       
    50                 response.add(flags_msg.send_self());
       
    51 
       
    52                 response.add(
       
    53                     ClientFlags(add_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_self(),
       
    54                 );
       
    55             };
       
    56         }
       
    57         Chat(msg) => {
       
    58             response.add(
       
    59                 ChatMsg {
       
    60                     nick: server.clients[client_id].nick.clone(),
       
    61                     msg,
       
    62                 }
       
    63                 .send_all()
       
    64                 .in_lobby()
       
    65                 .but_self(),
       
    66             );
       
    67         }
       
    68         JoinRoom(name, _password) => {
       
    69             let room = server.rooms.iter().find(|(_, r)| r.name == name);
       
    70             let room_id = room.map(|(_, r)| r.id);
       
    71 
       
    72             let client = &mut server.clients[client_id];
       
    73 
       
    74             if let Some((_, room)) = room {
       
    75                 if client.protocol_number != room.protocol_number {
       
    76                     response.add(
       
    77                         Warning("Room version incompatible to your Hedgewars version!".to_string())
       
    78                             .send_self(),
       
    79                     );
       
    80                 } else if room.is_join_restricted() {
       
    81                     response.add(
       
    82                         Warning(
       
    83                             "Access denied. This room currently doesn't allow joining.".to_string(),
       
    84                         )
       
    85                         .send_self(),
       
    86                     );
       
    87                 } else if room.players_number == u8::max_value() {
       
    88                     response.add(Warning("This room is already full".to_string()).send_self());
       
    89                 } else if let Some(room_id) = room_id {
       
    90                     super::common::enter_room(server, client_id, room_id, response);
       
    91                 }
       
    92             } else {
       
    93                 response.add(Warning("No such room.".to_string()).send_self());
       
    94             }
       
    95         }
       
    96         Follow(nick) => {
       
    97             if let Some(HWClient {
       
    98                 room_id: Some(room_id),
       
    99                 ..
       
   100             }) = server.find_client(&nick)
       
   101             {
       
   102                 let room = &server.rooms[*room_id];
       
   103                 response.add(Joining(room.name.clone()).send_self());
       
   104                 super::common::enter_room(server, client_id, *room_id, response);
       
   105             }
       
   106         }
       
   107         SetServerVar(var) => {
       
   108             if !server.clients[client_id].is_admin() {
       
   109                 response.add(Warning("Access denied.".to_string()).send_self());
       
   110             } else {
       
   111                 match var {
       
   112                     ServerVar::MOTDNew(msg) => server.greetings.for_latest_protocol = msg,
       
   113                     ServerVar::MOTDOld(msg) => server.greetings.for_old_protocols = msg,
       
   114                     ServerVar::LatestProto(n) => server.latest_protocol = n,
       
   115                 }
       
   116             }
       
   117         }
       
   118         GetServerVar => {
       
   119             if !server.clients[client_id].is_admin() {
       
   120                 response.add(Warning("Access denied.".to_string()).send_self());
       
   121             } else {
       
   122                 let vars: Vec<_> = [
       
   123                     ServerVar::MOTDNew(server.greetings.for_latest_protocol.clone()),
       
   124                     ServerVar::MOTDOld(server.greetings.for_old_protocols.clone()),
       
   125                     ServerVar::LatestProto(server.latest_protocol),
       
   126                 ]
       
   127                 .iter()
       
   128                 .flat_map(|v| v.to_protocol())
       
   129                 .collect();
       
   130                 response.add(ServerVars(vars).send_self());
       
   131             }
       
   132         }
       
   133         Rnd(v) => {
       
   134             response.add(rnd_reply(&v).send_self());
       
   135         }
       
   136         Stats => {
       
   137             let mut protocols: HashSet<_> = server
       
   138                 .clients
       
   139                 .iter()
       
   140                 .map(|(_, c)| c.protocol_number)
       
   141                 .chain(server.rooms.iter().map(|(_, r)| r.protocol_number))
       
   142                 .collect();
       
   143             let mut protocols: Vec<_> = protocols.drain().collect();
       
   144             protocols.sort();
       
   145 
       
   146             let mut html = Vec::with_capacity(protocols.len() + 2);
       
   147 
       
   148             html.push("<table>".to_string());
       
   149             for protocol in protocols {
       
   150                 html.push(format!(
       
   151                     "<tr><td>{}</td><td>{}</td><td>{}</td></tr>",
       
   152                     super::utils::protocol_version_string(protocol),
       
   153                     server.protocol_clients(protocol).count(),
       
   154                     server.protocol_rooms(protocol).count()
       
   155                 ));
       
   156             }
       
   157             html.push("</table>".to_string());
       
   158 
       
   159             response.add(Warning(html.join("")).send_self());
       
   160         }
       
   161         List => warn!("Deprecated LIST message received"),
       
   162         _ => warn!("Incorrect command in lobby state"),
       
   163     }
       
   164 }