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(), |