diff --git a/src/cli.rs b/src/cli.rs index 59c356a5a..dd39569ca 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -57,7 +57,7 @@ impl Interface for Session { } fn handle_login_error(&mut self, err: &str) -> bool { - self.lc.write().unwrap().handle_login_error(err, self) + handle_login_error(self.lc.clone(), err, self) } fn handle_peer_info(&mut self, pi: PeerInfo) { diff --git a/src/client.rs b/src/client.rs index f08f50ffd..bf11c4b6d 100644 --- a/src/client.rs +++ b/src/client.rs @@ -892,6 +892,8 @@ pub struct LoginConfigHandler { pub supported_encoding: Option<(bool, bool)>, pub restarting_remote_device: bool, pub force_relay: bool, + pub direct: Option, + pub received: bool, } impl Deref for LoginConfigHandler { @@ -929,6 +931,8 @@ impl LoginConfigHandler { self.supported_encoding = None; self.restarting_remote_device = false; self.force_relay = !self.get_option("force-always-relay").is_empty(); + self.direct = None; + self.received = false; } /// Check if the client should auto login. @@ -1338,32 +1342,6 @@ impl LoginConfigHandler { } } - /// Handle login error. - /// Return true if the password is wrong, return false if there's an actual error. - pub fn handle_login_error(&mut self, err: &str, interface: &impl Interface) -> bool { - if err == "Wrong Password" { - self.password = Default::default(); - interface.msgbox("re-input-password", err, "Do you want to enter again?", ""); - true - } else if err == "No Password Access" { - self.password = Default::default(); - interface.msgbox( - "wait-remote-accept-nook", - "Prompt", - "Please wait for the remote side to accept your session request...", - "", - ); - true - } else { - if err.contains(SCRAP_X11_REQUIRED) { - interface.msgbox("error", "Login Error", err, SCRAP_X11_REF_URL); - } else { - interface.msgbox("error", "Login Error", err, ""); - } - false - } - } - /// Get user name. /// Return the name of the given peer. If the peer has no name, return the name in the config. /// @@ -1726,6 +1704,36 @@ fn _input_os_password(p: String, activate: bool, interface: impl Interface) { interface.send(Data::Message(msg_out)); } +/// Handle login error. +/// Return true if the password is wrong, return false if there's an actual error. +pub fn handle_login_error( + lc: Arc>, + err: &str, + interface: &impl Interface, +) -> bool { + if err == "Wrong Password" { + lc.write().unwrap().password = Default::default(); + interface.msgbox("re-input-password", err, "Do you want to enter again?", ""); + true + } else if err == "No Password Access" { + lc.write().unwrap().password = Default::default(); + interface.msgbox( + "wait-remote-accept-nook", + "Prompt", + "Please wait for the remote side to accept your session request...", + "", + ); + true + } else { + if err.contains(SCRAP_X11_REQUIRED) { + interface.msgbox("error", "Login Error", err, SCRAP_X11_REF_URL); + } else { + interface.msgbox("error", "Login Error", err, ""); + } + false + } +} + /// Handle hash message sent by peer. /// Hash will be used for login. /// @@ -1815,6 +1823,7 @@ pub trait Interface: Send + Clone + 'static + Sized { fn handle_login_error(&mut self, err: &str) -> bool; fn handle_peer_info(&mut self, pi: PeerInfo); fn set_force_relay(&mut self, direct: bool, received: bool); + fn set_connection_info(&mut self, direct: bool, received: bool); fn is_file_transfer(&self) -> bool; fn is_port_forward(&self) -> bool; fn is_rdp(&self) -> bool; @@ -1990,11 +1999,10 @@ lazy_static::lazy_static! { /// * `title` - The title of the message. /// * `text` - The text of the message. #[inline] -pub fn check_if_retry(msgtype: &str, title: &str, text: &str) -> bool { +pub fn check_if_retry(msgtype: &str, title: &str, text: &str, retry_for_relay: bool) -> bool { msgtype == "error" && title == "Connection Error" - && (text.contains("10054") - || text.contains("104") + && ((text.contains("10054") || text.contains("104")) && retry_for_relay || (!text.to_lowercase().contains("offline") && !text.to_lowercase().contains("exist") && !text.to_lowercase().contains("handshake") diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 326857d3f..ceddbc004 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -107,6 +107,7 @@ impl Remote { SERVER_CLIPBOARD_ENABLED.store(true, Ordering::SeqCst); SERVER_FILE_TRANSFER_ENABLED.store(true, Ordering::SeqCst); self.handler.set_connection_type(peer.is_secured(), direct); // flutter -> connection_ready + self.handler.set_connection_info(direct, false); // just build for now #[cfg(not(windows))] @@ -144,7 +145,10 @@ impl Remote { } Ok(ref bytes) => { last_recv_time = Instant::now(); - received = true; + if !received { + received = true; + self.handler.set_connection_info(direct, true); + } self.data_count.fetch_add(bytes.len(), Ordering::Relaxed); if !self.handle_msg_from_peer(bytes, &mut peer).await { break diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 434086445..6f115571c 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -1,8 +1,8 @@ use crate::client::io_loop::Remote; use crate::client::{ - check_if_retry, handle_hash, handle_login_from_ui, handle_test_delay, input_os_password, - load_config, send_mouse, start_video_audio_threads, FileManager, Key, LoginConfigHandler, - QualityStatus, KEY_MAP, + check_if_retry, handle_hash, handle_login_error, handle_login_from_ui, handle_test_delay, + input_os_password, load_config, send_mouse, start_video_audio_threads, FileManager, Key, + LoginConfigHandler, QualityStatus, KEY_MAP, }; use crate::common::GrabState; use crate::keyboard; @@ -658,12 +658,15 @@ impl Interface for Session { } fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str) { - let retry = check_if_retry(msgtype, title, text); + let direct = self.lc.read().unwrap().direct.unwrap_or_default(); + let received = self.lc.read().unwrap().received; + let retry_for_relay = direct && !received; + let retry = check_if_retry(msgtype, title, text, retry_for_relay); self.ui_handler.msgbox(msgtype, title, text, link, retry); } fn handle_login_error(&mut self, err: &str) -> bool { - self.lc.write().unwrap().handle_login_error(err, self) + handle_login_error(self.lc.clone(), err, self) } fn handle_peer_info(&mut self, mut pi: PeerInfo) { @@ -746,6 +749,12 @@ impl Interface for Session { } } + fn set_connection_info(&mut self, direct: bool, received: bool) { + let mut lc = self.lc.write().unwrap(); + lc.direct = Some(direct); + lc.received = received; + } + fn set_force_relay(&mut self, direct: bool, received: bool) { let mut lc = self.lc.write().unwrap(); lc.force_relay = false;