From 461a87bce91e68822fe3e2d755956980a4c2263f Mon Sep 17 00:00:00 2001 From: 21pages Date: Mon, 25 Jul 2022 19:35:15 +0800 Subject: [PATCH] feat: pc restart Signed-off-by: 21pages --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + libs/hbb_common/protos/message.proto | 2 ++ src/client.rs | 12 +++++++++++- src/ipc.rs | 2 +- src/lang/cn.rs | 6 ++++++ src/lang/cs.rs | 6 ++++++ src/lang/da.rs | 6 ++++++ src/lang/de.rs | 6 ++++++ src/lang/eo.rs | 6 ++++++ src/lang/es.rs | 6 ++++++ src/lang/fr.rs | 6 ++++++ src/lang/hu.rs | 6 ++++++ src/lang/id.rs | 6 ++++++ src/lang/it.rs | 6 ++++++ src/lang/ptbr.rs | 6 ++++++ src/lang/ru.rs | 6 ++++++ src/lang/sk.rs | 6 ++++++ src/lang/template.rs | 6 ++++++ src/lang/tr.rs | 6 ++++++ src/lang/tw.rs | 6 ++++++ src/server/connection.rs | 22 ++++++++++++++++++++++ src/ui/cm.css | 4 ++++ src/ui/cm.rs | 10 ++++++---- src/ui/cm.tis | 14 ++++++++++++-- src/ui/header.tis | 7 +++++++ src/ui/index.tis | 1 + src/ui/msgbox.tis | 2 +- src/ui/remote.rs | 24 ++++++++++++++++++++++-- src/ui/remote.tis | 2 ++ 30 files changed, 198 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca2804394..e8f235f6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4017,6 +4017,7 @@ dependencies = [ "simple_rc", "sys-locale", "sysinfo", + "system_shutdown", "tray-item", "trayicon", "uuid", @@ -4637,6 +4638,15 @@ dependencies = [ "version-compare 0.1.0", ] +[[package]] +name = "system_shutdown" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035e081d603551d8d78db27d2232913269c749ea67648c369100049820406a14" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "tap" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index bd1232498..7f185db6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,6 +76,7 @@ rdev = { git = "https://github.com/open-trade/rdev" } ctrlc = "3.2" arboard = "2.0" #minreq = { version = "2.4", features = ["punycode", "https-native"] } +system_shutdown = "3.0.0" [target.'cfg(target_os = "windows")'.dependencies] #systray = { git = "https://github.com/open-trade/systray-rs" } diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 7b4bc3787..3a8f14421 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -426,6 +426,7 @@ message PermissionInfo { Clipboard = 2; Audio = 3; File = 4; + Restart = 5; } Permission permission = 1; @@ -544,6 +545,7 @@ message Misc { bool refresh_video = 10; bool video_received = 12; BackNotification back_notification = 13; + bool restart_remote_device = 14; } } diff --git a/src/client.rs b/src/client.rs index c2428a1af..0c54b8a5a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -785,6 +785,7 @@ pub struct LoginConfigHandler { features: Option, session_id: u64, pub supported_encoding: Option<(bool, bool)>, + pub restarting_remote_device: bool, } impl Deref for LoginConfigHandler { @@ -810,6 +811,7 @@ impl LoginConfigHandler { self.config = config; self.session_id = rand::random(); self.supported_encoding = None; + self.restarting_remote_device = false; } pub fn should_auto_login(&self) -> String { @@ -1144,7 +1146,7 @@ impl LoginConfigHandler { let my_id = Config::get_id(); let mut lr = LoginRequest { username: self.id.clone(), - password:password.into(), + password: password.into(), my_id, my_name: crate::username(), option: self.get_option_message(true).into(), @@ -1180,6 +1182,14 @@ impl LoginConfigHandler { msg_out.set_misc(misc); msg_out } + + pub fn restart_remote_device(&self) -> Message { + let mut misc = Misc::new(); + misc.set_restart_remote_device(true); + let mut msg_out = Message::new(); + msg_out.set_misc(misc); + msg_out + } } pub enum MediaData { diff --git a/src/ipc.rs b/src/ipc.rs index 9ada67dbd..6d2dd102f 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -141,6 +141,7 @@ pub enum Data { audio: bool, file: bool, file_transfer_enabled: bool, + restart: bool, }, ChatMessage { text: String, @@ -170,7 +171,6 @@ pub enum Data { ClipboardFileEnabled(bool), PrivacyModeState((i32, PrivacyModeState)), TestRendezvousServer, - Bool((String, Option)), Keyboard(DataKeyboard), KeyboardResponse(DataKeyboardResponse), Mouse(DataMouse), diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 9c23de91f..2e173739c 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", "同时使用两种密码"), ("Set permanent password", "设置固定密码"), ("Set temporary password length", "设置临时密码长度"), + ("Enable Remote Restart", "允许远程重启"), + ("Allow remote restart", "允许远程重启"), + ("Restart Remote Device", "重启远程电脑"), + ("Are you sure you want to restart", "确定要重启"), + ("Restarting Remote Device", "正在重启远程设备"), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", "远程设备正在重启, 请关闭当前提示框, 并在一段时间后使用永久密码重新连接"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 510a50c45..da5ae70a5 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 5489a6b74..3825c447d 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index e54377195..c64c15a57 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index d0c6511a6..52fb8649f 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 24b1122ef..16ab1a5fb 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index e928b6939..555e52d1f 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 8f182cdda..e7df21be7 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index d26706f87..60b1b8f11 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index dffeb4773..ef8c60ba2 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 390bbf968..aef3b5315 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 1c5a79cb3..919918cfd 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index dc255dd2b..10b5c97d2 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index fa8ef8cfb..2fc0aef47 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index a54cc7099..385c66b78 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", ""), ("Set permanent password", ""), ("Set temporary password length", ""), + ("Enable Remote Restart", ""), + ("Allow remote restart", ""), + ("Restart Remote Device", ""), + ("Are you sure you want to restart", ""), + ("Restarting Remote Device", ""), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 6eeeb8e72..fe597ac25 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Use both passwords", "同時使用兩種密碼"), ("Set permanent password", "設定固定密碼"), ("Set temporary password length", "設定臨時密碼長度"), + ("Enable Remote Restart", "允許遠程重啓"), + ("Allow remote restart", "允許遠程重啓"), + ("Restart Remote Device", "重啓遠程電腦"), + ("Are you sure you want to restart", "确定要重启"), + ("Restarting Remote Device", "正在重啓遠程設備"), + ("Remote device is restarting, please close this message box and reconnect with permanent password after a while", "遠程設備正在重啓,請關閉當前提示框,並在一段時間後使用永久密碼重新連接"), ].iter().cloned().collect(); } diff --git a/src/server/connection.rs b/src/server/connection.rs index 590dc198b..53903ee2d 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -31,6 +31,8 @@ use std::sync::{ atomic::{AtomicI64, Ordering}, mpsc as std_mpsc, }; +#[cfg(not(any(target_os = "android", target_os = "ios")))] +use system_shutdown; pub type Sender = mpsc::UnboundedSender<(Instant, Arc)>; @@ -79,6 +81,7 @@ pub struct Connection { clipboard: bool, audio: bool, file: bool, + restart: bool, last_test_delay: i64, lock_after_session_end: bool, show_remote_cursor: bool, // by peer @@ -166,6 +169,7 @@ impl Connection { clipboard: Config::get_option("enable-clipboard").is_empty(), audio: Config::get_option("enable-audio").is_empty(), file: Config::get_option("enable-file-transfer").is_empty(), + restart: Config::get_option("enable-remote-restart").is_empty(), last_test_delay: 0, lock_after_session_end: false, show_remote_cursor: false, @@ -204,6 +208,9 @@ impl Connection { if !conn.file { conn.send_permission(Permission::File, false).await; } + if !conn.restart { + conn.send_permission(Permission::Restart, false).await; + } let mut test_delay_timer = time::interval_at(Instant::now() + TEST_DELAY_TIMEOUT, TEST_DELAY_TIMEOUT); let mut last_recv_time = Instant::now(); @@ -281,6 +288,9 @@ impl Connection { conn.file = enabled; conn.send_permission(Permission::File, enabled).await; conn.send_to_cm(ipc::Data::ClipboardFileEnabled(conn.file_transfer_enabled())); + } else if &name == "restart" { + conn.restart = enabled; + conn.send_permission(Permission::Restart, enabled).await; } } ipc::Data::RawMessage(bytes) => { @@ -766,6 +776,7 @@ impl Connection { audio: self.audio, file: self.file, file_transfer_enabled: self.file_transfer_enabled(), + restart: self.restart, }); } @@ -1208,6 +1219,17 @@ impl Connection { SESSIONS.lock().unwrap().remove(&self.lr.my_id); return false; } + + Some(misc::Union::RestartRemoteDevice(_)) => + { + #[cfg(not(any(target_os = "android", target_os = "ios")))] + if self.restart { + match system_shutdown::reboot() { + Ok(_) => log::info!("Restart by the peer"), + Err(e) => log::error!("Failed to restart:{}", e), + } + } + } _ => {} }, _ => {} diff --git a/src/ui/cm.css b/src/ui/cm.css index d9d003d53..0832c6251 100644 --- a/src/ui/cm.css +++ b/src/ui/cm.css @@ -104,6 +104,10 @@ icon.file { background:url('data: image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAMAAADVRocKAAAAUVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////8IN+deAAAAGnRSTlMAH+CAESEN8jyZkcIb5N/ONy3vmHhmiGjUm7UwS+YAAAHZSURBVGje7dnbboMwDIBhBwgQoFAO7Ta//4NOqCAXYZQstatq4r+r5ubrgQSpg8iyC4ZURa+PlIpQYGiwrzyeHtYZjAL8T05O4H8BbbKvFgRa4NoBU8pXeYEkDDgaaLQBcwJrmeErJQB/7wes3QBWGnCIX0+AQycL1PO6BMwPa0nA4ZxbgTvOjUYMGPHRnZkQAY4mxPZBjmy53E7ukSkFKYB/D4XsWZQx64sCeYebOogGsoOBYvv6/UCb8F0IOBZ0TlP6lEYdANY350AJqB9/qPVuOI5evw4A1hgLigAlepnyxW80bcCcwN++A2s82Vcu02ta+ceq9BoL5KGTTRwQPlpqA3gCnwWU2kCDgeWRQPj2jAPCDxgCMjhI6uZnToDpvd/BJeFrJQB/fsAa02gCt3mi1wNuy8GgBNDZlysBNNSrADVSjcJl6vCpUn6jOdx0kz0q6PMhQRa4465SFKhx35cgUCBTwj2/NHwZAb71qR8GEP2H1XcmAtBPTEO67GP6FUUAIKGABbDLQ0EArhN2sAIGesRO+iyy+RMAjckVTlMCKFVAbh/4Af9OPgG61SkDVco3BQGT3GXaDAnTIAcYZDuBTwGsAGDxuBFeAQqIqwoFMlAVLrHr/wId5MPt0nilGgAAAABJRU5ErkJggg=='); } +icon.restart { + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAB7BAAAewQHDaVRTAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAbhJREFUWIXVlrFqFGEUhb+7UYxaWCQKlrKKxaZSQVGDJih2tj6MD2DnMwiWvoAIRnENIpZiYxEro6IooiS7SPwsMgNLkk3mjmYmnmb45/73nMNwz/x/qH3gMu2gH6rAU+Blw+Lngau4jpmGxVF7qp1iPWjaQKnZ2WnXbuP/NqAeUPc3ZkA9XDwvqc+BVWCgPlJ7tRwUKThZce819b46VH+pfXVRXVO/q2cSul3VOgZUl0ejq86r39TXI8mqZKDuDEwCw3IREQvAbWAGmMsQZQ0sAl3gHPB1Q+0e8BuYzRDuy2yOiFVgaUxtRf0ETGc4syk4rc6PqU0Cx9j8Zf6dAeAK8Fi9sUXtFjABvEgxJlNwRP2svlNPjbw/q35U36oTFbnyMSwabxb/gB/qA3VBHagrauV7RW0DRfP1IvMlXqkXkhz1DYyQTKtHa/Z2VVMx3IiI+PI3/bCHjuOpFrSnAMpL6QfgTcMGesDx0kBr2BMzsNyi/vtQu8CJlgwsRbZDnWP90NkKaxHxJMOXMqAeAn5u0ydwMCKGY+qbkB3C2W3EKWoXk5zVoHbUZ+6Mh7tl4G4F8RJ3qvL+AfV3r5Vdpj70AAAAAElFTkSuQmCC'); +} + div.buttons { width: *; border-spacing: 0.5em; diff --git a/src/ui/cm.rs b/src/ui/cm.rs index fe5738c31..45038d753 100644 --- a/src/ui/cm.rs +++ b/src/ui/cm.rs @@ -14,7 +14,7 @@ use hbb_common::{ fs, get_version_number, log, message_proto::*, protobuf::Message as _, - tokio::{self, sync::mpsc, task::spawn_blocking} + tokio::{self, sync::mpsc, task::spawn_blocking}, }; use sciter::{make_args, Element, Value, HELEMENT}; use std::{ @@ -90,6 +90,7 @@ impl ConnectionManager { clipboard: bool, audio: bool, file: bool, + restart: bool, tx: mpsc::UnboundedSender, ) { self.call( @@ -104,7 +105,8 @@ impl ConnectionManager { keyboard, clipboard, audio, - file + file, + restart ), ); self.write().unwrap().senders.insert(id, tx); @@ -489,11 +491,11 @@ async fn start_ipc(cm: ConnectionManager) { } Ok(Some(data)) => { match data { - Data::Login{id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, file_transfer_enabled} => { + Data::Login{id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, file_transfer_enabled, restart} => { log::debug!("conn_id: {}", id); conn_id = id; tx_file.send(ClipboardFileData::Enable((id, file_transfer_enabled))).ok(); - cm.add_connection(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, tx.clone()); + cm.add_connection(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, restart, tx.clone()); } Data::Close => { tx_file.send(ClipboardFileData::Enable((conn_id, false))).ok(); diff --git a/src/ui/cm.tis b/src/ui/cm.tis index 9bc92661b..4708acea5 100644 --- a/src/ui/cm.tis +++ b/src/ui/cm.tis @@ -46,6 +46,7 @@ class Body: Reactor.Component
+
} {c.port_forward ?
Port Forwarding: {c.port_forward}
: ""}
@@ -108,6 +109,15 @@ class Body: Reactor.Component }); } + event click $(icon.restart) { + var { cid, connection } = this; + checkClickTime(function() { + connection.restart = !connection.restart; + body.update(); + handler.switch_permission(cid, "restart", connection.restart); + }); + } + event click $(button#accept) { var { cid, connection } = this; checkClickTime(function() { @@ -266,7 +276,7 @@ function bring_to_top(idx=-1) { } } -handler.addConnection = function(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file) { +handler.addConnection = function(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, restart) { stdout.println("new connection #" + id + ": " + peer_id); var conn; connections.map(function(c) { @@ -283,7 +293,7 @@ handler.addConnection = function(id, is_file_transfer, port_forward, peer_id, na port_forward: port_forward, name: name, authorized: authorized, time: new Date(), keyboard: keyboard, clipboard: clipboard, msgs: [], unreaded: 0, - audio: audio, file: file + audio: audio, file: file, restart: restart }); body.cur = connections.length - 1; bring_to_top(); diff --git a/src/ui/header.tis b/src/ui/header.tis index 6ee3cad01..7ff160e6d 100644 --- a/src/ui/header.tis +++ b/src/ui/header.tis @@ -188,6 +188,7 @@ class Header: Reactor.Component { {handler.get_audit_server() &&
  • {translate('Note')}
  • }
    {keyboard_enabled && (pi.platform == "Linux" || pi.sas_enabled) ?
  • {translate('Insert')} Ctrl + Alt + Del
  • : ""} + {restart_enabled && (pi.platform == "Linux" || pi.platform == "Windows" || pi.platform == "Mac OS") ?
  • {translate('Restart Remote Device')}
  • : ""} {keyboard_enabled ?
  • {translate('Insert Lock')}
  • : ""} {keyboard_enabled && pi.platform == "Windows" && pi.sas_enabled ?
  • {translate("Block user input")}
  • : ""}
  • {translate('Refresh')}
  • @@ -301,6 +302,12 @@ class Header: Reactor.Component { handler.ctrl_alt_del(); } + event click $(#restart_remote_device) { + msgbox("restart-confirmation", translate("Restart Remote Device"), translate("Are you sure you want to restart") + " " + pi.username + "@" + pi.hostname + "(" + get_id() + ") ?", function(res=null) { + if (res != null) handler.restart_remote_device(); + }); + } + event click $(#lock-screen) { handler.lock_screen(); } diff --git a/src/ui/index.tis b/src/ui/index.tis index 296527681..747a59df8 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -274,6 +274,7 @@ class MyIdMenu: Reactor.Component {
  • {svg_checkmark}{translate('Enable Keyboard/Mouse')}
  • {svg_checkmark}{translate('Enable Clipboard')}
  • {svg_checkmark}{translate('Enable File Transfer')}
  • +
  • {svg_checkmark}{translate('Enable Remote Restart')}
  • {svg_checkmark}{translate('Enable TCP Tunneling')}
  • diff --git a/src/ui/msgbox.tis b/src/ui/msgbox.tis index b4ca1c490..a622a45b8 100644 --- a/src/ui/msgbox.tis +++ b/src/ui/msgbox.tis @@ -91,7 +91,7 @@ class MsgboxComponent: Reactor.Component { var color = this.getColor(); var icon = this.getIcon(color); var content = this.getContent(); - var hasCancel = this.type.indexOf("error") < 0 && this.type.indexOf("nocancel") < 0; + var hasCancel = this.type.indexOf("error") < 0 && this.type.indexOf("nocancel") < 0 && this.type != "restarting"; var hasOk = this.type != "connecting" && this.type != "success" && this.type.indexOf("nook") < 0; var hasClose = this.type.indexOf("hasclose") >= 0; var show_progress = this.type == "connecting"; diff --git a/src/ui/remote.rs b/src/ui/remote.rs index a738d7f8b..787e2a000 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -234,6 +234,7 @@ impl sciter::EventHandler for Handler { fn has_hwcodec(); fn supported_hwcodec(); fn change_prefer_codec(); + fn restart_remote_device(); } } @@ -634,6 +635,16 @@ impl Handler { self.send(Data::Message(msg)); } + fn restart_remote_device(&mut self) { + self.lc.write().unwrap().restarting_remote_device = true; + let msg = self.lc.write().unwrap().restart_remote_device(); + self.send(Data::Message(msg)); + } + + pub fn is_restarting_remote_device(&self) -> bool { + self.lc.read().unwrap().restarting_remote_device + } + fn t(&self, name: String) -> String { crate::client::translate(name) } @@ -1487,8 +1498,13 @@ impl Remote { } } } else { - log::info!("Reset by the peer"); - self.handler.msgbox("error", "Connection Error", "Reset by the peer"); + if self.handler.is_restarting_remote_device() { + log::info!("Restart remote device"); + self.handler.msgbox("restarting", "Restarting Remote Device", "Remote device is restarting, please close this message box and reconnect with permanent password after a while"); + } else { + log::info!("Reset by the peer"); + self.handler.msgbox("error", "Connection Error", "Reset by the peer"); + } break; } } @@ -2319,6 +2335,10 @@ impl Remote { self.handler .call2("setPermission", &make_args!("file", p.enabled)); } + Permission::Restart => { + self.handler + .call2("setPermission", &make_args!("restart", p.enabled)); + } } } Some(misc::Union::SwitchDisplay(s)) => { diff --git a/src/ui/remote.tis b/src/ui/remote.tis index 8bc29ac60..65e7e5030 100644 --- a/src/ui/remote.tis +++ b/src/ui/remote.tis @@ -11,6 +11,7 @@ var keyboard_enabled = true; // server side var clipboard_enabled = true; // server side var audio_enabled = true; // server side var file_enabled = true; // server side +var restart_enabled = true; // server side var scroll_body = $(body); handler.setDisplay = function(x, y, w, h) { @@ -505,6 +506,7 @@ handler.setPermission = function(name, enabled) { if (name == "audio") audio_enabled = enabled; if (name == "file") file_enabled = enabled; if (name == "clipboard") clipboard_enabled = enabled; + if (name == "restart") restart_enabled = enabled; input_blocked = false; header.update(); });