rust/hedgewars-server/src/handlers/inanteroom.rs
changeset 16120 5febd2bc5372
parent 16019 c40f5e27aaf0
equal deleted inserted replaced
16119:278533359a93 16120:5febd2bc5372
    18     num::NonZeroU16,
    18     num::NonZeroU16,
    19 };
    19 };
    20 
    20 
    21 pub enum LoginResult {
    21 pub enum LoginResult {
    22     Unchanged,
    22     Unchanged,
    23     Complete,
    23     Complete(HwAnteroomClient),
    24     Exit,
    24     Exit,
    25 }
    25 }
    26 
    26 
    27 fn completion_result<'a, I>(
    27 fn get_completion_result(
    28     mut other_clients: I,
    28     anteroom: &mut HwAnteroom,
    29     client: &mut HwAnteroomClient,
    29     client_id: ClientId,
    30     response: &mut super::Response,
    30     response: &mut super::Response,
    31 ) -> LoginResult
    31 ) -> LoginResult {
    32 where
    32     #[cfg(feature = "official-server")]
    33     I: Iterator<Item = &'a HwClient>,
    33     {
    34 {
    34         let client = anteroom.get_client(client_id);
    35     let has_nick_clash = other_clients.any(|c| c.nick == *client.nick.as_ref().unwrap());
    35         response.request_io(super::IoTask::CheckRegistered {
       
    36             nick: client.nick.as_ref().unwrap().clone(),
       
    37         });
       
    38         LoginResult::Unchanged
       
    39     }
    36 
    40 
    37     if has_nick_clash {
    41     #[cfg(not(feature = "official-server"))]
    38         client.nick = None;
    42     {
    39         response.add(Notice("NickAlreadyInUse".to_string()).send_self());
    43         LoginResult::Complete(anteroom.remove_client(client_id).unwrap())
    40         LoginResult::Unchanged
       
    41     } else {
       
    42         #[cfg(feature = "official-server")]
       
    43         {
       
    44             response.request_io(super::IoTask::CheckRegistered {
       
    45                 nick: client.nick.as_ref().unwrap().clone(),
       
    46             });
       
    47             LoginResult::Unchanged
       
    48         }
       
    49 
       
    50         #[cfg(not(feature = "official-server"))]
       
    51         {
       
    52             LoginResult::Complete
       
    53         }
       
    54     }
    44     }
    55 }
    45 }
    56 
    46 
    57 pub fn handle(
    47 pub fn handle(
    58     server_state: &mut super::ServerState,
    48     anteroom: &mut HwAnteroom,
    59     client_id: ClientId,
    49     client_id: ClientId,
    60     response: &mut super::Response,
    50     response: &mut super::Response,
    61     message: HwProtocolMessage,
    51     message: HwProtocolMessage,
    62 ) -> LoginResult {
    52 ) -> LoginResult {
    63     //todo!("Handle parsing of empty nicks")
    53     //todo!("Handle parsing of empty nicks")
    64     match message {
    54     match message {
    65         HwProtocolMessage::Quit(_) => {
    55         HwProtocolMessage::Quit(_) => {
    66             response.add(Bye("User quit".to_string()).send_self());
    56             response.add(Bye("User quit".to_string()).send_self());
    67             LoginResult::Exit
    57             LoginResult::Exit
    68         }
    58         }
    69         HwProtocolMessage::Nick(nick) => {
    59         HwProtocolMessage::Nick(nick, token) => {
    70             let client = &mut server_state.anteroom.clients[client_id];
    60             if anteroom.nick_taken(&nick) {
       
    61                 response.add(Notice("NickAlreadyInUse".to_string()).send_self());
       
    62                 return LoginResult::Unchanged;
       
    63             }
       
    64             let reconnect = token
       
    65                 .map(|t| anteroom.get_nick_token(&nick) == Some(&t[..]))
       
    66                 .unwrap_or(false);
       
    67             let client = anteroom.get_client_mut(client_id);
    71 
    68 
    72             if client.nick.is_some() {
    69             if client.nick.is_some() {
    73                 response.error(NICKNAME_PROVIDED);
    70                 response.error(NICKNAME_PROVIDED);
    74                 LoginResult::Unchanged
    71                 LoginResult::Unchanged
    75             } else if is_name_illegal(&nick) {
    72             } else if is_name_illegal(&nick) {
    76                 response.add(Bye(ILLEGAL_CLIENT_NAME.to_string()).send_self());
    73                 response.add(Bye(ILLEGAL_CLIENT_NAME.to_string()).send_self());
    77                 LoginResult::Exit
    74                 LoginResult::Exit
    78             } else {
    75             } else {
    79                 client.nick = Some(nick.clone());
    76                 client.nick = Some(nick.clone());
       
    77                 let protocol_number = client.protocol_number;
       
    78                 if reconnect {
       
    79                     client.is_registered = reconnect;
       
    80                 } else if let Some(token) = anteroom.register_nick_token(&nick) {
       
    81                     response.add(Token(token.to_string()).send_self());
       
    82                 }
    80                 response.add(Nick(nick).send_self());
    83                 response.add(Nick(nick).send_self());
    81 
    84 
    82                 if client.protocol_number.is_some() {
    85                 if protocol_number.is_some() {
    83                     completion_result(server_state.server.iter_clients(), client, response)
    86                     get_completion_result(anteroom, client_id, response)
    84                 } else {
    87                 } else {
    85                     LoginResult::Unchanged
    88                     LoginResult::Unchanged
    86                 }
    89                 }
    87             }
    90             }
    88         }
    91         }
    89         HwProtocolMessage::Proto(proto) => {
    92         HwProtocolMessage::Proto(proto) => {
    90             let client = &mut server_state.anteroom.clients[client_id];
    93             let client = anteroom.get_client_mut(client_id);
    91             if client.protocol_number.is_some() {
    94             if client.protocol_number.is_some() {
    92                 response.error(PROTOCOL_PROVIDED);
    95                 response.error(PROTOCOL_PROVIDED);
    93                 LoginResult::Unchanged
    96                 LoginResult::Unchanged
    94             } else if proto < 48 {
    97             } else if proto < 48 {
    95                 response.add(Bye(PROTOCOL_TOO_OLD.to_string()).send_self());
    98                 response.add(Bye(PROTOCOL_TOO_OLD.to_string()).send_self());
    97             } else {
   100             } else {
    98                 client.protocol_number = NonZeroU16::new(proto);
   101                 client.protocol_number = NonZeroU16::new(proto);
    99                 response.add(Proto(proto).send_self());
   102                 response.add(Proto(proto).send_self());
   100 
   103 
   101                 if client.nick.is_some() {
   104                 if client.nick.is_some() {
   102                     completion_result(server_state.server.iter_clients(), client, response)
   105                     get_completion_result(anteroom, client_id, response)
   103                 } else {
   106                 } else {
   104                     LoginResult::Unchanged
   107                     LoginResult::Unchanged
   105                 }
   108                 }
   106             }
   109             }
   107         }
   110         }
   108         #[cfg(feature = "official-server")]
   111         #[cfg(feature = "official-server")]
   109         HwProtocolMessage::Password(hash, salt) => {
   112         HwProtocolMessage::Password(hash, salt) => {
   110             let client = &server_state.anteroom.clients[client_id];
   113             let client = anteroom.get_client(client_id);
   111 
   114 
   112             if let (Some(nick), Some(protocol)) = (client.nick.as_ref(), client.protocol_number) {
   115             if let (Some(nick), Some(protocol)) = (client.nick.as_ref(), client.protocol_number) {
   113                 response.request_io(super::IoTask::GetAccount {
   116                 response.request_io(super::IoTask::GetAccount {
   114                     nick: nick.clone(),
   117                     nick: nick.clone(),
   115                     protocol: protocol.get(),
   118                     protocol: protocol.get(),
   121 
   124 
   122             LoginResult::Unchanged
   125             LoginResult::Unchanged
   123         }
   126         }
   124         #[cfg(feature = "official-server")]
   127         #[cfg(feature = "official-server")]
   125         HwProtocolMessage::Checker(protocol, nick, password) => {
   128         HwProtocolMessage::Checker(protocol, nick, password) => {
   126             let client = &mut server_state.anteroom.clients[client_id];
   129             let client = anteroom.get_client_mut(client_id);
   127             if protocol == 0 {
   130             if protocol == 0 {
   128                 response.error("Bad number.");
   131                 response.error("Bad number.");
   129                 LoginResult::Unchanged
   132                 LoginResult::Unchanged
   130             } else {
   133             } else {
   131                 client.protocol_number = NonZeroU16::new(protocol);
   134                 client.protocol_number = NonZeroU16::new(protocol);
   140                 }
   143                 }
   141 
   144 
   142                 #[cfg(feature = "official-server")]
   145                 #[cfg(feature = "official-server")]
   143                 {
   146                 {
   144                     response.add(LogonPassed.send_self());
   147                     response.add(LogonPassed.send_self());
   145                     LoginResult::Complete
   148                     anteroom.remember_nick(nick);
       
   149                     LoginResult::Complete(anteroom.remove_client(client_id).unwrap())
   146                 }
   150                 }
   147             }
   151             }
   148         }
   152         }
   149         _ => {
   153         _ => {
   150             warn!("Incorrect command in anteroom");
   154             warn!("Incorrect command in anteroom");