feat: pc restart

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2022-07-25 19:35:15 +08:00
parent 4d1d90a090
commit 461a87bce9
30 changed files with 198 additions and 11 deletions

10
Cargo.lock generated
View File

@ -4017,6 +4017,7 @@ dependencies = [
"simple_rc", "simple_rc",
"sys-locale", "sys-locale",
"sysinfo", "sysinfo",
"system_shutdown",
"tray-item", "tray-item",
"trayicon", "trayicon",
"uuid", "uuid",
@ -4637,6 +4638,15 @@ dependencies = [
"version-compare 0.1.0", "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]] [[package]]
name = "tap" name = "tap"
version = "1.0.1" version = "1.0.1"

View File

@ -76,6 +76,7 @@ rdev = { git = "https://github.com/open-trade/rdev" }
ctrlc = "3.2" ctrlc = "3.2"
arboard = "2.0" arboard = "2.0"
#minreq = { version = "2.4", features = ["punycode", "https-native"] } #minreq = { version = "2.4", features = ["punycode", "https-native"] }
system_shutdown = "3.0.0"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
#systray = { git = "https://github.com/open-trade/systray-rs" } #systray = { git = "https://github.com/open-trade/systray-rs" }

View File

@ -426,6 +426,7 @@ message PermissionInfo {
Clipboard = 2; Clipboard = 2;
Audio = 3; Audio = 3;
File = 4; File = 4;
Restart = 5;
} }
Permission permission = 1; Permission permission = 1;
@ -544,6 +545,7 @@ message Misc {
bool refresh_video = 10; bool refresh_video = 10;
bool video_received = 12; bool video_received = 12;
BackNotification back_notification = 13; BackNotification back_notification = 13;
bool restart_remote_device = 14;
} }
} }

View File

@ -785,6 +785,7 @@ pub struct LoginConfigHandler {
features: Option<Features>, features: Option<Features>,
session_id: u64, session_id: u64,
pub supported_encoding: Option<(bool, bool)>, pub supported_encoding: Option<(bool, bool)>,
pub restarting_remote_device: bool,
} }
impl Deref for LoginConfigHandler { impl Deref for LoginConfigHandler {
@ -810,6 +811,7 @@ impl LoginConfigHandler {
self.config = config; self.config = config;
self.session_id = rand::random(); self.session_id = rand::random();
self.supported_encoding = None; self.supported_encoding = None;
self.restarting_remote_device = false;
} }
pub fn should_auto_login(&self) -> String { pub fn should_auto_login(&self) -> String {
@ -1144,7 +1146,7 @@ impl LoginConfigHandler {
let my_id = Config::get_id(); let my_id = Config::get_id();
let mut lr = LoginRequest { let mut lr = LoginRequest {
username: self.id.clone(), username: self.id.clone(),
password:password.into(), password: password.into(),
my_id, my_id,
my_name: crate::username(), my_name: crate::username(),
option: self.get_option_message(true).into(), option: self.get_option_message(true).into(),
@ -1180,6 +1182,14 @@ impl LoginConfigHandler {
msg_out.set_misc(misc); msg_out.set_misc(misc);
msg_out 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 { pub enum MediaData {

View File

@ -141,6 +141,7 @@ pub enum Data {
audio: bool, audio: bool,
file: bool, file: bool,
file_transfer_enabled: bool, file_transfer_enabled: bool,
restart: bool,
}, },
ChatMessage { ChatMessage {
text: String, text: String,
@ -170,7 +171,6 @@ pub enum Data {
ClipboardFileEnabled(bool), ClipboardFileEnabled(bool),
PrivacyModeState((i32, PrivacyModeState)), PrivacyModeState((i32, PrivacyModeState)),
TestRendezvousServer, TestRendezvousServer,
Bool((String, Option<bool>)),
Keyboard(DataKeyboard), Keyboard(DataKeyboard),
KeyboardResponse(DataKeyboardResponse), KeyboardResponse(DataKeyboardResponse),
Mouse(DataMouse), Mouse(DataMouse),

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", "同时使用两种密码"), ("Use both passwords", "同时使用两种密码"),
("Set permanent password", "设置固定密码"), ("Set permanent password", "设置固定密码"),
("Set temporary password length", "设置临时密码长度"), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", ""), ("Use both passwords", ""),
("Set permanent password", ""), ("Set permanent password", ""),
("Set temporary password length", ""), ("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(); ].iter().cloned().collect();
} }

View File

@ -293,5 +293,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use both passwords", "同時使用兩種密碼"), ("Use both passwords", "同時使用兩種密碼"),
("Set permanent password", "設定固定密碼"), ("Set permanent password", "設定固定密碼"),
("Set temporary password length", "設定臨時密碼長度"), ("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(); ].iter().cloned().collect();
} }

View File

@ -31,6 +31,8 @@ use std::sync::{
atomic::{AtomicI64, Ordering}, atomic::{AtomicI64, Ordering},
mpsc as std_mpsc, mpsc as std_mpsc,
}; };
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use system_shutdown;
pub type Sender = mpsc::UnboundedSender<(Instant, Arc<Message>)>; pub type Sender = mpsc::UnboundedSender<(Instant, Arc<Message>)>;
@ -79,6 +81,7 @@ pub struct Connection {
clipboard: bool, clipboard: bool,
audio: bool, audio: bool,
file: bool, file: bool,
restart: bool,
last_test_delay: i64, last_test_delay: i64,
lock_after_session_end: bool, lock_after_session_end: bool,
show_remote_cursor: bool, // by peer show_remote_cursor: bool, // by peer
@ -166,6 +169,7 @@ impl Connection {
clipboard: Config::get_option("enable-clipboard").is_empty(), clipboard: Config::get_option("enable-clipboard").is_empty(),
audio: Config::get_option("enable-audio").is_empty(), audio: Config::get_option("enable-audio").is_empty(),
file: Config::get_option("enable-file-transfer").is_empty(), file: Config::get_option("enable-file-transfer").is_empty(),
restart: Config::get_option("enable-remote-restart").is_empty(),
last_test_delay: 0, last_test_delay: 0,
lock_after_session_end: false, lock_after_session_end: false,
show_remote_cursor: false, show_remote_cursor: false,
@ -204,6 +208,9 @@ impl Connection {
if !conn.file { if !conn.file {
conn.send_permission(Permission::File, false).await; conn.send_permission(Permission::File, false).await;
} }
if !conn.restart {
conn.send_permission(Permission::Restart, false).await;
}
let mut test_delay_timer = let mut test_delay_timer =
time::interval_at(Instant::now() + TEST_DELAY_TIMEOUT, TEST_DELAY_TIMEOUT); time::interval_at(Instant::now() + TEST_DELAY_TIMEOUT, TEST_DELAY_TIMEOUT);
let mut last_recv_time = Instant::now(); let mut last_recv_time = Instant::now();
@ -281,6 +288,9 @@ impl Connection {
conn.file = enabled; conn.file = enabled;
conn.send_permission(Permission::File, enabled).await; conn.send_permission(Permission::File, enabled).await;
conn.send_to_cm(ipc::Data::ClipboardFileEnabled(conn.file_transfer_enabled())); 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) => { ipc::Data::RawMessage(bytes) => {
@ -766,6 +776,7 @@ impl Connection {
audio: self.audio, audio: self.audio,
file: self.file, file: self.file,
file_transfer_enabled: self.file_transfer_enabled(), file_transfer_enabled: self.file_transfer_enabled(),
restart: self.restart,
}); });
} }
@ -1208,6 +1219,17 @@ impl Connection {
SESSIONS.lock().unwrap().remove(&self.lr.my_id); SESSIONS.lock().unwrap().remove(&self.lr.my_id);
return false; 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),
}
}
}
_ => {} _ => {}
}, },
_ => {} _ => {}

View File

@ -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=='); 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 { div.buttons {
width: *; width: *;
border-spacing: 0.5em; border-spacing: 0.5em;

View File

@ -14,7 +14,7 @@ use hbb_common::{
fs, get_version_number, log, fs, get_version_number, log,
message_proto::*, message_proto::*,
protobuf::Message as _, 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 sciter::{make_args, Element, Value, HELEMENT};
use std::{ use std::{
@ -90,6 +90,7 @@ impl ConnectionManager {
clipboard: bool, clipboard: bool,
audio: bool, audio: bool,
file: bool, file: bool,
restart: bool,
tx: mpsc::UnboundedSender<Data>, tx: mpsc::UnboundedSender<Data>,
) { ) {
self.call( self.call(
@ -104,7 +105,8 @@ impl ConnectionManager {
keyboard, keyboard,
clipboard, clipboard,
audio, audio,
file file,
restart
), ),
); );
self.write().unwrap().senders.insert(id, tx); self.write().unwrap().senders.insert(id, tx);
@ -489,11 +491,11 @@ async fn start_ipc(cm: ConnectionManager) {
} }
Ok(Some(data)) => { Ok(Some(data)) => {
match 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); log::debug!("conn_id: {}", id);
conn_id = id; conn_id = id;
tx_file.send(ClipboardFileData::Enable((id, file_transfer_enabled))).ok(); 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 => { Data::Close => {
tx_file.send(ClipboardFileData::Enable((conn_id, false))).ok(); tx_file.send(ClipboardFileData::Enable((conn_id, false))).ok();

View File

@ -46,6 +46,7 @@ class Body: Reactor.Component
<div class={!c.clipboard ? "disabled" : ""} title={translate('Allow using clipboard')}><icon .clipboard /></div> <div class={!c.clipboard ? "disabled" : ""} title={translate('Allow using clipboard')}><icon .clipboard /></div>
<div class={!c.audio ? "disabled" : ""} title={translate('Allow hearing sound')}><icon .audio /></div> <div class={!c.audio ? "disabled" : ""} title={translate('Allow hearing sound')}><icon .audio /></div>
<div class={!c.file ? "disabled" : ""} title={translate('Allow file copy and paste')}><icon .file /></div> <div class={!c.file ? "disabled" : ""} title={translate('Allow file copy and paste')}><icon .file /></div>
<div class={!c.restart ? "disabled" : ""} title={translate('Allow remote restart')}><icon .restart /></div>
</div>} </div>}
{c.port_forward ? <div>Port Forwarding: {c.port_forward}</div> : ""} {c.port_forward ? <div>Port Forwarding: {c.port_forward}</div> : ""}
<div style="size:*"/> <div style="size:*"/>
@ -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) { event click $(button#accept) {
var { cid, connection } = this; var { cid, connection } = this;
checkClickTime(function() { 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); stdout.println("new connection #" + id + ": " + peer_id);
var conn; var conn;
connections.map(function(c) { connections.map(function(c) {
@ -283,7 +293,7 @@ handler.addConnection = function(id, is_file_transfer, port_forward, peer_id, na
port_forward: port_forward, port_forward: port_forward,
name: name, authorized: authorized, time: new Date(), name: name, authorized: authorized, time: new Date(),
keyboard: keyboard, clipboard: clipboard, msgs: [], unreaded: 0, keyboard: keyboard, clipboard: clipboard, msgs: [], unreaded: 0,
audio: audio, file: file audio: audio, file: file, restart: restart
}); });
body.cur = connections.length - 1; body.cur = connections.length - 1;
bring_to_top(); bring_to_top();

View File

@ -188,6 +188,7 @@ class Header: Reactor.Component {
{handler.get_audit_server() && <li #note>{translate('Note')}</li>} {handler.get_audit_server() && <li #note>{translate('Note')}</li>}
<div .separator /> <div .separator />
{keyboard_enabled && (pi.platform == "Linux" || pi.sas_enabled) ? <li #ctrl-alt-del>{translate('Insert')} Ctrl + Alt + Del</li> : ""} {keyboard_enabled && (pi.platform == "Linux" || pi.sas_enabled) ? <li #ctrl-alt-del>{translate('Insert')} Ctrl + Alt + Del</li> : ""}
{restart_enabled && (pi.platform == "Linux" || pi.platform == "Windows" || pi.platform == "Mac OS") ? <li #restart_remote_device>{translate('Restart Remote Device')}</li> : ""}
{keyboard_enabled ? <li #lock-screen>{translate('Insert Lock')}</li> : ""} {keyboard_enabled ? <li #lock-screen>{translate('Insert Lock')}</li> : ""}
{keyboard_enabled && pi.platform == "Windows" && pi.sas_enabled ? <li #block-input>{translate("Block user input")}</li> : ""} {keyboard_enabled && pi.platform == "Windows" && pi.sas_enabled ? <li #block-input>{translate("Block user input")}</li> : ""}
<li #refresh>{translate('Refresh')}</li> <li #refresh>{translate('Refresh')}</li>
@ -301,6 +302,12 @@ class Header: Reactor.Component {
handler.ctrl_alt_del(); 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) { event click $(#lock-screen) {
handler.lock_screen(); handler.lock_screen();
} }

View File

@ -274,6 +274,7 @@ class MyIdMenu: Reactor.Component {
<li #enable-keyboard><span>{svg_checkmark}</span>{translate('Enable Keyboard/Mouse')}</li> <li #enable-keyboard><span>{svg_checkmark}</span>{translate('Enable Keyboard/Mouse')}</li>
<li #enable-clipboard><span>{svg_checkmark}</span>{translate('Enable Clipboard')}</li> <li #enable-clipboard><span>{svg_checkmark}</span>{translate('Enable Clipboard')}</li>
<li #enable-file-transfer><span>{svg_checkmark}</span>{translate('Enable File Transfer')}</li> <li #enable-file-transfer><span>{svg_checkmark}</span>{translate('Enable File Transfer')}</li>
<li #enable-remote-restart><span>{svg_checkmark}</span>{translate('Enable Remote Restart')}</li>
<li #enable-tunnel><span>{svg_checkmark}</span>{translate('Enable TCP Tunneling')}</li> <li #enable-tunnel><span>{svg_checkmark}</span>{translate('Enable TCP Tunneling')}</li>
<AudioInputs /> <AudioInputs />
<Enhancements /> <Enhancements />

View File

@ -91,7 +91,7 @@ class MsgboxComponent: Reactor.Component {
var color = this.getColor(); var color = this.getColor();
var icon = this.getIcon(color); var icon = this.getIcon(color);
var content = this.getContent(); 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 hasOk = this.type != "connecting" && this.type != "success" && this.type.indexOf("nook") < 0;
var hasClose = this.type.indexOf("hasclose") >= 0; var hasClose = this.type.indexOf("hasclose") >= 0;
var show_progress = this.type == "connecting"; var show_progress = this.type == "connecting";

View File

@ -234,6 +234,7 @@ impl sciter::EventHandler for Handler {
fn has_hwcodec(); fn has_hwcodec();
fn supported_hwcodec(); fn supported_hwcodec();
fn change_prefer_codec(); fn change_prefer_codec();
fn restart_remote_device();
} }
} }
@ -634,6 +635,16 @@ impl Handler {
self.send(Data::Message(msg)); 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 { fn t(&self, name: String) -> String {
crate::client::translate(name) crate::client::translate(name)
} }
@ -1487,8 +1498,13 @@ impl Remote {
} }
} }
} else { } else {
log::info!("Reset by the peer"); if self.handler.is_restarting_remote_device() {
self.handler.msgbox("error", "Connection Error", "Reset by the peer"); 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; break;
} }
} }
@ -2319,6 +2335,10 @@ impl Remote {
self.handler self.handler
.call2("setPermission", &make_args!("file", p.enabled)); .call2("setPermission", &make_args!("file", p.enabled));
} }
Permission::Restart => {
self.handler
.call2("setPermission", &make_args!("restart", p.enabled));
}
} }
} }
Some(misc::Union::SwitchDisplay(s)) => { Some(misc::Union::SwitchDisplay(s)) => {

View File

@ -11,6 +11,7 @@ var keyboard_enabled = true; // server side
var clipboard_enabled = true; // server side var clipboard_enabled = true; // server side
var audio_enabled = true; // server side var audio_enabled = true; // server side
var file_enabled = true; // server side var file_enabled = true; // server side
var restart_enabled = true; // server side
var scroll_body = $(body); var scroll_body = $(body);
handler.setDisplay = function(x, y, w, h) { handler.setDisplay = function(x, y, w, h) {
@ -505,6 +506,7 @@ handler.setPermission = function(name, enabled) {
if (name == "audio") audio_enabled = enabled; if (name == "audio") audio_enabled = enabled;
if (name == "file") file_enabled = enabled; if (name == "file") file_enabled = enabled;
if (name == "clipboard") clipboard_enabled = enabled; if (name == "clipboard") clipboard_enabled = enabled;
if (name == "restart") restart_enabled = enabled;
input_blocked = false; input_blocked = false;
header.update(); header.update();
}); });