rust/hedgewars-server/src/handlers/inlobby.rs
changeset 15463 a158ff8f84ef
parent 15096 e935b1ad23f3
child 15504 4cc9ec732392
equal deleted inserted replaced
15462:e7c059ac6e54 15463:a158ff8f84ef
     1 use mio;
     1 use mio;
     2 
     2 
     3 use super::common::rnd_reply;
     3 use super::{common::rnd_reply, strings::*};
     4 use crate::{
     4 use crate::{
     5     core::{
     5     core::{
     6         client::HwClient,
     6         client::HwClient,
     7         server::HwServer,
     7         server::{AccessError, CreateRoomError, HwServer, JoinRoomError},
     8         types::{ClientId, ServerVar},
     8         types::{ClientId, ServerVar},
     9     },
     9     },
    10     protocol::messages::{
    10     protocol::messages::{
    11         add_flags, remove_flags, server_chat, HwProtocolMessage, HwServerMessage::*,
    11         add_flags, remove_flags, server_chat, HwProtocolMessage, HwServerMessage::*,
    12         ProtocolFlags as Flags,
    12         ProtocolFlags as Flags,
    21     client_id: ClientId,
    21     client_id: ClientId,
    22     response: &mut super::Response,
    22     response: &mut super::Response,
    23     message: HwProtocolMessage,
    23     message: HwProtocolMessage,
    24 ) {
    24 ) {
    25     use crate::protocol::messages::HwProtocolMessage::*;
    25     use crate::protocol::messages::HwProtocolMessage::*;
       
    26 
    26     match message {
    27     match message {
    27         CreateRoom(name, password) => {
    28         CreateRoom(name, password) => match server.create_room(client_id, name, password) {
    28             if is_name_illegal(&name) {
    29             Err(CreateRoomError::InvalidName) => response.warn(ILLEGAL_ROOM_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             Err(CreateRoomError::AlreadyExists) => response.warn(ROOM_EXISTS),
    30             } else if server.has_room(&name) {
    31             Ok((client, room)) => {
    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(
    32                 response.add(
    45                     RoomAdd(room.info(Some(&client)))
    33                     RoomAdd(room.info(Some(&client)))
    46                         .send_all()
    34                         .send_all()
    47                         .with_protocol(room.protocol_number),
    35                         .with_protocol(room.protocol_number),
    48                 );
    36                 );
    49                 response.add(RoomJoined(vec![client.nick.clone()]).send_self());
    37                 response.add(RoomJoined(vec![client.nick.clone()]).send_self());
    50                 response.add(flags_msg.send_self());
    38                 response.add(
    51 
    39                     ClientFlags(
       
    40                         add_flags(&[Flags::RoomMaster, Flags::Ready]),
       
    41                         vec![client.nick.clone()],
       
    42                     )
       
    43                     .send_self(),
       
    44                 );
    52                 response.add(
    45                 response.add(
    53                     ClientFlags(add_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_self(),
    46                     ClientFlags(add_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_self(),
    54                 );
    47                 );
    55             };
    48             }
    56         }
    49         },
    57         Chat(msg) => {
    50         Chat(msg) => {
    58             response.add(
    51             response.add(
    59                 ChatMsg {
    52                 ChatMsg {
    60                     nick: server.clients[client_id].nick.clone(),
    53                     nick: server.get_client_nick(client_id).to_string(),
    61                     msg,
    54                     msg,
    62                 }
    55                 }
    63                 .send_all()
    56                 .send_all()
    64                 .in_lobby()
    57                 .in_lobby()
    65                 .but_self(),
    58                 .but_self(),
    66             );
    59             );
    67         }
    60         }
    68         JoinRoom(name, _password) => {
    61         JoinRoom(name, _password) => match server.join_room_by_name(client_id, &name) {
    69             let room = server.rooms.iter().find(|(_, r)| r.name == name);
    62             Err(error) => super::common::get_room_join_error(error, response),
    70             let room_id = room.map(|(_, r)| r.id);
    63             Ok((client, room, room_clients)) => {
    71 
    64                 super::common::get_room_join_data(client, room, room_clients, response)
    72             let client = &mut server.clients[client_id];
    65             }
    73 
    66         },
    74             if let Some((_, room)) = room {
    67         Follow(nick) => {
    75                 if client.protocol_number != room.protocol_number {
    68             if let Some(client) = server.find_client(&nick) {
    76                     response.add(
    69                 if let Some(room_id) = client.room_id {
    77                         Warning("Room version incompatible to your Hedgewars version!".to_string())
    70                     match server.join_room(client_id, room_id) {
    78                             .send_self(),
    71                         Err(error) => super::common::get_room_join_error(error, response),
    79                     );
    72                         Ok((client, room, room_clients)) => {
    80                 } else if room.is_join_restricted() {
    73                             super::common::get_room_join_data(client, room, room_clients, response)
    81                     response.add(
    74                         }
    82                         Warning(
    75                     }
    83                             "Access denied. This room currently doesn't allow joining.".to_string(),
    76                 } else {
    84                         )
    77                     response.warn(NO_ROOM);
    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                 }
    78                 }
    92             } else {
    79             } else {
    93                 response.add(Warning("No such room.".to_string()).send_self());
    80                 response.warn(NO_USER);
    94             }
    81             }
    95         }
    82         }
    96         Follow(nick) => {
    83         SetServerVar(var) => match server.set_var(client_id, var) {
    97             if let Some(HwClient {
    84             Err(AccessError()) => response.warn(ACCESS_DENIED),
    98                 room_id: Some(room_id),
    85             Ok(()) => response.add(server_chat(VARIABLE_UPDATED.to_string()).send_self()),
    99                 ..
    86         },
   100             }) = server.find_client(&nick)
    87         GetServerVar => match server.get_vars(client_id) {
   101             {
    88             Err(AccessError()) => response.warn(ACCESS_DENIED),
   102                 let room = &server.rooms[*room_id];
    89             Ok(vars) => {
   103                 response.add(Joining(room.name.clone()).send_self());
    90                 response.add(
   104                 super::common::enter_room(server, client_id, *room_id, response);
    91                     ServerVars(vars.iter().flat_map(|v| v.to_protocol()).collect()).send_self(),
       
    92                 );
   105             }
    93             }
   106         }
    94         },
   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) => {
    95         Rnd(v) => {
   134             response.add(rnd_reply(&v).send_self());
    96             response.add(rnd_reply(&v).send_self());
   135         }
    97         }
   136         Stats => {
    98         Stats => match server.get_used_protocols(client_id) {
   137             let mut protocols: HashSet<_> = server
    99             Err(AccessError()) => response.warn(ACCESS_DENIED),
   138                 .clients
   100             Ok(protocols) => {
   139                 .iter()
   101                 let mut html = Vec::with_capacity(protocols.len() + 2);
   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 
   102 
   146             let mut html = Vec::with_capacity(protocols.len() + 2);
   103                 html.push("<table>".to_string());
       
   104                 for protocol in protocols {
       
   105                     html.push(format!(
       
   106                         "<tr><td>{}</td><td>{}</td><td>{}</td></tr>",
       
   107                         super::utils::protocol_version_string(protocol),
       
   108                         server.protocol_clients(protocol).count(),
       
   109                         server.protocol_rooms(protocol).count()
       
   110                     ));
       
   111                 }
       
   112                 html.push("</table>".to_string());
   147 
   113 
   148             html.push("<table>".to_string());
   114                 response.add(Warning(html.join("")).send_self());
   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             }
   115             }
   157             html.push("</table>".to_string());
   116         },
   158 
       
   159             response.add(Warning(html.join("")).send_self());
       
   160         }
       
   161         List => warn!("Deprecated LIST message received"),
   117         List => warn!("Deprecated LIST message received"),
   162         _ => warn!("Incorrect command in lobby state"),
   118         _ => warn!("Incorrect command in lobby state"),
   163     }
   119     }
   164 }
   120 }