mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
Merge master
This commit is contained in:
@@ -1033,10 +1033,6 @@ impl LoginConfigHandler {
|
||||
msg.lock_after_session_end = BoolOption::Yes.into();
|
||||
n += 1;
|
||||
}
|
||||
if self.get_toggle_option("privacy-mode") {
|
||||
msg.privacy_mode = BoolOption::Yes.into();
|
||||
n += 1;
|
||||
}
|
||||
if self.get_toggle_option("disable-audio") {
|
||||
msg.disable_audio = BoolOption::Yes.into();
|
||||
n += 1;
|
||||
@@ -1060,6 +1056,23 @@ impl LoginConfigHandler {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_option_message_after_login(&self) -> Option<OptionMessage> {
|
||||
if self.is_port_forward || self.is_file_transfer {
|
||||
return None;
|
||||
}
|
||||
let mut n = 0;
|
||||
let mut msg = OptionMessage::new();
|
||||
if self.get_toggle_option("privacy-mode") {
|
||||
msg.privacy_mode = BoolOption::Yes.into();
|
||||
n += 1;
|
||||
}
|
||||
if n > 0 {
|
||||
Some(msg)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the image quality option.
|
||||
/// Return [`ImageQuality`] if the option is valid, otherwise return `None`.
|
||||
///
|
||||
@@ -1277,6 +1290,7 @@ impl LoginConfigHandler {
|
||||
my_name: crate::username(),
|
||||
option: self.get_option_message(true).into(),
|
||||
session_id: self.session_id,
|
||||
version: crate::VERSION.to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
if self.is_file_transfer {
|
||||
|
||||
@@ -3,7 +3,10 @@ use std::{
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use hbb_common::{log, message_proto::{VideoFrame, video_frame}};
|
||||
use hbb_common::{
|
||||
log,
|
||||
message_proto::{video_frame, VideoFrame},
|
||||
};
|
||||
|
||||
const MAX_LATENCY: i64 = 500;
|
||||
const MIN_LATENCY: i64 = 100;
|
||||
@@ -89,3 +92,12 @@ impl ToString for CodecFormat {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct QualityStatus {
|
||||
pub speed: Option<String>,
|
||||
pub fps: Option<i32>,
|
||||
pub delay: Option<i32>,
|
||||
pub target_bitrate: Option<i32>,
|
||||
pub codec_format: Option<CodecFormat>,
|
||||
}
|
||||
|
||||
283
src/flutter.rs
283
src/flutter.rs
@@ -1,6 +1,9 @@
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc, Mutex, RwLock,
|
||||
},
|
||||
};
|
||||
|
||||
use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer};
|
||||
@@ -114,6 +117,9 @@ impl Session {
|
||||
}
|
||||
lc.set_option(name, value);
|
||||
}
|
||||
// TODO
|
||||
// input_os_password
|
||||
// restart_remote_device
|
||||
|
||||
/// Input the OS password.
|
||||
pub fn input_os_password(&self, pass: String, activate: bool) {
|
||||
@@ -505,6 +511,26 @@ impl Session {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_quality_status(&self, status: QualityStatus) {
|
||||
const NULL: String = String::new();
|
||||
self.push_event(
|
||||
"update_quality_status",
|
||||
vec![
|
||||
("speed", &status.speed.map_or(NULL, |it| it)),
|
||||
("fps", &status.fps.map_or(NULL, |it| it.to_string())),
|
||||
("delay", &status.delay.map_or(NULL, |it| it.to_string())),
|
||||
(
|
||||
"target_bitrate",
|
||||
&status.target_bitrate.map_or(NULL, |it| it.to_string()),
|
||||
),
|
||||
(
|
||||
"codec_format",
|
||||
&status.codec_format.map_or(NULL, |it| it.to_string()),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl FileManager for Session {}
|
||||
@@ -599,7 +625,14 @@ impl Interface for Session {
|
||||
}
|
||||
|
||||
async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream) {
|
||||
handle_test_delay(t, peer).await;
|
||||
if !t.from_client {
|
||||
self.update_quality_status(QualityStatus {
|
||||
delay: Some(t.last_delay as _),
|
||||
target_bitrate: Some(t.target_bitrate as _),
|
||||
..Default::default()
|
||||
});
|
||||
handle_test_delay(t, peer).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,6 +647,9 @@ struct Connection {
|
||||
write_jobs: Vec<fs::TransferJob>,
|
||||
timer: Interval,
|
||||
last_update_jobs_status: (Instant, HashMap<i32, u64>),
|
||||
data_count: Arc<AtomicUsize>,
|
||||
frame_count: Arc<AtomicUsize>,
|
||||
video_format: CodecFormat,
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
@@ -646,6 +682,9 @@ impl Connection {
|
||||
write_jobs: Vec::new(),
|
||||
timer: time::interval(SEC30),
|
||||
last_update_jobs_status: (Instant::now(), Default::default()),
|
||||
data_count: Arc::new(AtomicUsize::new(0)),
|
||||
frame_count: Arc::new(AtomicUsize::new(0)),
|
||||
video_format: CodecFormat::Unknown,
|
||||
};
|
||||
let key = Config::get_option("key");
|
||||
let token = Config::get_option("access_token");
|
||||
@@ -659,6 +698,9 @@ impl Connection {
|
||||
("direct", &direct.to_string()),
|
||||
],
|
||||
);
|
||||
|
||||
let mut status_timer = time::interval(Duration::new(1, 0));
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
res = peer.next() => {
|
||||
@@ -671,14 +713,20 @@ impl Connection {
|
||||
}
|
||||
Ok(ref bytes) => {
|
||||
last_recv_time = Instant::now();
|
||||
conn.data_count.fetch_add(bytes.len(), Ordering::Relaxed);
|
||||
if !conn.handle_msg_from_peer(bytes, &mut peer).await {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::info!("Reset by the peer");
|
||||
session.msgbox("error", "Connection Error", "Reset by the peer");
|
||||
if session.lc.read().unwrap().restarting_remote_device {
|
||||
log::info!("Restart remote device");
|
||||
session.msgbox("restarting", "Restarting Remote Device", "remote_restarting_tip");
|
||||
} else {
|
||||
log::info!("Reset by the peer");
|
||||
session.msgbox("error", "Connection Error", "Reset by the peer");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -704,6 +752,16 @@ impl Connection {
|
||||
conn.timer = time::interval_at(Instant::now() + SEC30, SEC30);
|
||||
}
|
||||
}
|
||||
_ = status_timer.tick() => {
|
||||
let speed = conn.data_count.swap(0, Ordering::Relaxed);
|
||||
let speed = format!("{:.2}kB/s", speed as f32 / 1024 as f32);
|
||||
let fps = conn.frame_count.swap(0, Ordering::Relaxed) as _;
|
||||
conn.session.update_quality_status(QualityStatus {
|
||||
speed:Some(speed),
|
||||
fps:Some(fps),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
log::debug!("Exit io_loop of id={}", session.id);
|
||||
@@ -725,6 +783,14 @@ impl Connection {
|
||||
if !self.first_frame {
|
||||
self.first_frame = true;
|
||||
}
|
||||
let incomming_format = CodecFormat::from(&vf);
|
||||
if self.video_format != incomming_format {
|
||||
self.video_format = incomming_format.clone();
|
||||
self.session.update_quality_status(QualityStatus {
|
||||
codec_format: Some(incomming_format),
|
||||
..Default::default()
|
||||
})
|
||||
};
|
||||
if let Ok(true) = self.video_handler.handle_frame(vf) {
|
||||
let stream = self.session.events2ui.read().unwrap();
|
||||
stream.add(EventToUI::Rgba(ZeroCopyBuffer(
|
||||
@@ -786,113 +852,114 @@ impl Connection {
|
||||
vec![("x", &cp.x.to_string()), ("y", &cp.y.to_string())],
|
||||
);
|
||||
}
|
||||
Some(message::Union::FileResponse(fr)) => match fr.union {
|
||||
Some(file_response::Union::Dir(fd)) => {
|
||||
let mut entries = fd.entries.to_vec();
|
||||
if self.session.peer_platform() == "Windows" {
|
||||
fs::transform_windows_path(&mut entries);
|
||||
}
|
||||
let id = fd.id;
|
||||
self.session.push_event(
|
||||
"file_dir",
|
||||
vec![("value", &make_fd_to_json(fd)), ("is_local", "false")],
|
||||
);
|
||||
if let Some(job) = fs::get_job(id, &mut self.write_jobs) {
|
||||
job.set_files(entries);
|
||||
}
|
||||
}
|
||||
Some(file_response::Union::Block(block)) => {
|
||||
if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) {
|
||||
if let Err(_err) = job.write(block, None).await {
|
||||
// to-do: add "skip" for writing job
|
||||
Some(message::Union::FileResponse(fr)) => {
|
||||
match fr.union {
|
||||
Some(file_response::Union::Dir(fd)) => {
|
||||
let mut entries = fd.entries.to_vec();
|
||||
if self.session.peer_platform() == "Windows" {
|
||||
fs::transform_windows_path(&mut entries);
|
||||
}
|
||||
let id = fd.id;
|
||||
self.session.push_event(
|
||||
"file_dir",
|
||||
vec![("value", &make_fd_to_json(fd)), ("is_local", "false")],
|
||||
);
|
||||
if let Some(job) = fs::get_job(id, &mut self.write_jobs) {
|
||||
job.set_files(entries);
|
||||
}
|
||||
self.update_jobs_status();
|
||||
}
|
||||
}
|
||||
Some(file_response::Union::Done(d)) => {
|
||||
if let Some(job) = fs::get_job(d.id, &mut self.write_jobs) {
|
||||
job.modify_time();
|
||||
fs::remove_job(d.id, &mut self.write_jobs);
|
||||
Some(file_response::Union::Block(block)) => {
|
||||
if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) {
|
||||
if let Err(_err) = job.write(block, None).await {
|
||||
// to-do: add "skip" for writing job
|
||||
}
|
||||
self.update_jobs_status();
|
||||
}
|
||||
}
|
||||
self.handle_job_status(d.id, d.file_num, None);
|
||||
}
|
||||
Some(file_response::Union::Error(e)) => {
|
||||
self.handle_job_status(e.id, e.file_num, Some(e.error));
|
||||
}
|
||||
Some(file_response::Union::Digest(digest)) => {
|
||||
if digest.is_upload {
|
||||
if let Some(job) = fs::get_job(digest.id, &mut self.read_jobs) {
|
||||
if let Some(file) = job.files().get(digest.file_num as usize) {
|
||||
let read_path = get_string(&job.join(&file.name));
|
||||
let overwrite_strategy = job.default_overwrite_strategy();
|
||||
if let Some(overwrite) = overwrite_strategy {
|
||||
let req = FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(if overwrite {
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||
} else {
|
||||
file_transfer_send_confirm_request::Union::Skip(
|
||||
true,
|
||||
)
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req);
|
||||
let msg = new_send_confirm(req);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
} else {
|
||||
self.handle_override_file_confirm(
|
||||
digest.id,
|
||||
digest.file_num,
|
||||
read_path,
|
||||
true,
|
||||
);
|
||||
Some(file_response::Union::Done(d)) => {
|
||||
if let Some(job) = fs::get_job(d.id, &mut self.write_jobs) {
|
||||
job.modify_time();
|
||||
fs::remove_job(d.id, &mut self.write_jobs);
|
||||
}
|
||||
self.handle_job_status(d.id, d.file_num, None);
|
||||
}
|
||||
Some(file_response::Union::Error(e)) => {
|
||||
self.handle_job_status(e.id, e.file_num, Some(e.error));
|
||||
}
|
||||
Some(file_response::Union::Digest(digest)) => {
|
||||
if digest.is_upload {
|
||||
if let Some(job) = fs::get_job(digest.id, &mut self.read_jobs) {
|
||||
if let Some(file) = job.files().get(digest.file_num as usize) {
|
||||
let read_path = get_string(&job.join(&file.name));
|
||||
let overwrite_strategy = job.default_overwrite_strategy();
|
||||
if let Some(overwrite) = overwrite_strategy {
|
||||
let req = FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(if overwrite {
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||
} else {
|
||||
file_transfer_send_confirm_request::Union::Skip(
|
||||
true,
|
||||
)
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
job.confirm(&req);
|
||||
let msg = new_send_confirm(req);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
} else {
|
||||
self.handle_override_file_confirm(
|
||||
digest.id,
|
||||
digest.file_num,
|
||||
read_path,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Some(job) = fs::get_job(digest.id, &mut self.write_jobs) {
|
||||
if let Some(file) = job.files().get(digest.file_num as usize) {
|
||||
let write_path = get_string(&job.join(&file.name));
|
||||
let overwrite_strategy = job.default_overwrite_strategy();
|
||||
match fs::is_write_need_confirmation(&write_path, &digest) {
|
||||
Ok(res) => match res {
|
||||
DigestCheckResult::IsSame => {
|
||||
let msg= new_send_confirm(FileTransferSendConfirmRequest {
|
||||
} else {
|
||||
if let Some(job) = fs::get_job(digest.id, &mut self.write_jobs) {
|
||||
if let Some(file) = job.files().get(digest.file_num as usize) {
|
||||
let write_path = get_string(&job.join(&file.name));
|
||||
let overwrite_strategy = job.default_overwrite_strategy();
|
||||
match fs::is_write_need_confirmation(&write_path, &digest) {
|
||||
Ok(res) => match res {
|
||||
DigestCheckResult::IsSame => {
|
||||
let msg= new_send_confirm(FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(file_transfer_send_confirm_request::Union::Skip(true)),
|
||||
..Default::default()
|
||||
});
|
||||
self.session.send_msg(msg);
|
||||
}
|
||||
DigestCheckResult::NeedConfirm(digest) => {
|
||||
if let Some(overwrite) = overwrite_strategy {
|
||||
let msg = new_send_confirm(
|
||||
FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(if overwrite {
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||
} else {
|
||||
file_transfer_send_confirm_request::Union::Skip(true)
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
self.session.send_msg(msg);
|
||||
} else {
|
||||
self.handle_override_file_confirm(
|
||||
digest.id,
|
||||
digest.file_num,
|
||||
write_path.to_string(),
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
DigestCheckResult::NoSuchFile => {
|
||||
let msg = new_send_confirm(
|
||||
DigestCheckResult::NeedConfirm(digest) => {
|
||||
if let Some(overwrite) = overwrite_strategy {
|
||||
let msg = new_send_confirm(
|
||||
FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
union: Some(if overwrite {
|
||||
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||
} else {
|
||||
file_transfer_send_confirm_request::Union::Skip(true)
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
self.session.send_msg(msg);
|
||||
} else {
|
||||
self.handle_override_file_confirm(
|
||||
digest.id,
|
||||
digest.file_num,
|
||||
write_path.to_string(),
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
DigestCheckResult::NoSuchFile => {
|
||||
let msg = new_send_confirm(
|
||||
FileTransferSendConfirmRequest {
|
||||
id: digest.id,
|
||||
file_num: digest.file_num,
|
||||
@@ -900,19 +967,20 @@ impl Connection {
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
self.session.send_msg(msg);
|
||||
self.session.send_msg(msg);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
println!("error recving digest: {}", err);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
println!("error recving digest: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
Some(message::Union::Misc(misc)) => match misc.union {
|
||||
Some(misc::Union::AudioFormat(f)) => {
|
||||
self.audio_handler.handle_format(f); //
|
||||
@@ -931,6 +999,7 @@ impl Connection {
|
||||
Permission::Keyboard => "keyboard",
|
||||
Permission::Clipboard => "clipboard",
|
||||
Permission::Audio => "audio",
|
||||
Permission::Restart => "restart",
|
||||
_ => "",
|
||||
},
|
||||
&p.enabled.to_string(),
|
||||
@@ -1608,8 +1677,8 @@ pub mod connection_manager {
|
||||
id,
|
||||
file_num,
|
||||
mut files,
|
||||
overwrite_detection,
|
||||
} => {
|
||||
// in mobile, can_enable_override_detection is always true
|
||||
WRITE_JOBS.lock().unwrap().push(fs::TransferJob::new_write(
|
||||
id,
|
||||
"".to_string(),
|
||||
@@ -1625,7 +1694,7 @@ pub mod connection_manager {
|
||||
..Default::default()
|
||||
})
|
||||
.collect(),
|
||||
true,
|
||||
overwrite_detection,
|
||||
));
|
||||
}
|
||||
ipc::FS::CancelWrite { id } => {
|
||||
|
||||
@@ -644,25 +644,6 @@ unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *co
|
||||
// res = Session::get_option(arg);
|
||||
// }
|
||||
// }
|
||||
"server_id" => {
|
||||
res = ui_interface::get_id();
|
||||
}
|
||||
"temporary_password" => {
|
||||
res = ui_interface::temporary_password();
|
||||
}
|
||||
"permanent_password" => {
|
||||
res = ui_interface::permanent_password();
|
||||
}
|
||||
"connect_statue" => {
|
||||
res = ONLINE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.values()
|
||||
.max()
|
||||
.unwrap_or(&0)
|
||||
.clone()
|
||||
.to_string();
|
||||
}
|
||||
// File Action
|
||||
"get_home_dir" => {
|
||||
res = fs::get_home_as_string();
|
||||
@@ -683,6 +664,33 @@ unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *co
|
||||
// }
|
||||
// }
|
||||
// Server Side
|
||||
"local_option" => {
|
||||
if let Ok(arg) = arg.to_str() {
|
||||
res = LocalConfig::get_option(arg);
|
||||
}
|
||||
}
|
||||
"langs" => {
|
||||
res = crate::lang::LANGS.to_string();
|
||||
}
|
||||
"server_id" => {
|
||||
res = ui_interface::get_id();
|
||||
}
|
||||
"temporary_password" => {
|
||||
res = ui_interface::temporary_password();
|
||||
}
|
||||
"permanent_password" => {
|
||||
res = ui_interface::permanent_password();
|
||||
}
|
||||
"connect_statue" => {
|
||||
res = ONLINE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.values()
|
||||
.max()
|
||||
.unwrap_or(&0)
|
||||
.clone()
|
||||
.to_string();
|
||||
}
|
||||
#[cfg(not(any(target_os = "ios")))]
|
||||
"clients_state" => {
|
||||
res = get_clients_state();
|
||||
@@ -862,9 +870,22 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
"local_option" => {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
|
||||
if let Some(name) = m.get("name") {
|
||||
if let Some(value) = m.get("value") {
|
||||
LocalConfig::set_option(name.to_owned(), value.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// "input_os_password" => {
|
||||
// Session::input_os_password(value.to_owned(), true);
|
||||
// }
|
||||
"restart_remote_device" => {
|
||||
// TODO
|
||||
// Session::restart_remote_device();
|
||||
}
|
||||
// // File Action
|
||||
// "read_remote_dir" => {
|
||||
// if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
|
||||
|
||||
@@ -60,6 +60,7 @@ pub enum FS {
|
||||
id: i32,
|
||||
file_num: i32,
|
||||
files: Vec<(String, u64)>,
|
||||
overwrite_detection: bool,
|
||||
},
|
||||
CancelWrite {
|
||||
id: i32,
|
||||
|
||||
21
src/lang.rs
21
src/lang.rs
@@ -8,17 +8,18 @@ mod de;
|
||||
mod en;
|
||||
mod eo;
|
||||
mod es;
|
||||
mod hu;
|
||||
mod fr;
|
||||
mod hu;
|
||||
mod id;
|
||||
mod it;
|
||||
mod ja;
|
||||
mod pl;
|
||||
mod ptbr;
|
||||
mod ru;
|
||||
mod sk;
|
||||
mod tr;
|
||||
mod tw;
|
||||
mod vn;
|
||||
mod pl;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref LANGS: Value =
|
||||
@@ -41,6 +42,7 @@ lazy_static::lazy_static! {
|
||||
("tr", "Türkçe"),
|
||||
("vn", "Tiếng Việt"),
|
||||
("pl", "Polski"),
|
||||
("ja", "日本語"),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -87,16 +89,19 @@ pub fn translate_locale(name: String, locale: &str) -> String {
|
||||
"sk" => sk::T.deref(),
|
||||
"vn" => vn::T.deref(),
|
||||
"pl" => pl::T.deref(),
|
||||
"ja" => ja::T.deref(),
|
||||
_ => en::T.deref(),
|
||||
};
|
||||
if let Some(v) = m.get(&name as &str) {
|
||||
v.to_string()
|
||||
} else {
|
||||
if lang != "en" {
|
||||
if let Some(v) = en::T.get(&name as &str) {
|
||||
return v.to_string();
|
||||
if v.is_empty() {
|
||||
if lang != "en" {
|
||||
if let Some(v) = en::T.get(&name as &str) {
|
||||
return v.to_string();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return v.to_string();
|
||||
}
|
||||
name
|
||||
}
|
||||
name
|
||||
}
|
||||
|
||||
303
src/lang/ja.rs
Normal file
303
src/lang/ja.rs
Normal file
@@ -0,0 +1,303 @@
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
[
|
||||
("Status", "状態"),
|
||||
("Your Desktop", "デスクトップ"),
|
||||
("desk_tip", "このIDとパスワードであなたのデスクトップにアクセスできます。"),
|
||||
("Password", "パスワード"),
|
||||
("Ready", "準備完了"),
|
||||
("Established", "接続完了"),
|
||||
("connecting_status", "RuskDeskネットワークに接続中..."),
|
||||
("Enable Service", "サービスを有効化"),
|
||||
("Start Service", "サービスを開始"),
|
||||
("Service is running", "サービスは動作中"),
|
||||
("Service is not running", "サービスは動作していません"),
|
||||
("not_ready_status", "準備できていません。接続を確認してください。"),
|
||||
("Control Remote Desktop", "リモートのデスクトップを操作する"),
|
||||
("Transfer File", "ファイルを転送"),
|
||||
("Connect", "接続"),
|
||||
("Recent Sessions", "最近のセッション"),
|
||||
("Address Book", "アドレス帳"),
|
||||
("Confirmation", "確認用"),
|
||||
("TCP Tunneling", "TCPトンネリング"),
|
||||
("Remove", "削除"),
|
||||
("Refresh random password", "ランダムパスワードを再生成"),
|
||||
("Set your own password", "自分のパスワードを設定"),
|
||||
("Enable Keyboard/Mouse", "キーボード・マウスを有効化"),
|
||||
("Enable Clipboard", "クリップボードを有効化"),
|
||||
("Enable File Transfer", "ファイル転送を有効化"),
|
||||
("Enable TCP Tunneling", "TCPトンネリングを有効化"),
|
||||
("IP Whitelisting", "IPホワイトリスト"),
|
||||
("ID/Relay Server", "認証・中継サーバー"),
|
||||
("Stop service", "サービスを停止"),
|
||||
("Change ID", "IDを変更"),
|
||||
("Website", "公式サイト"),
|
||||
("About", "情報"),
|
||||
("Mute", "ミュート"),
|
||||
("Audio Input", "音声入力デバイス"),
|
||||
("Enhancements", "追加機能"),
|
||||
("Hardware Codec", "ハードウェア コーデック"),
|
||||
("Adaptive Bitrate", "アダプティブビットレート"),
|
||||
("ID Server", "認証サーバー"),
|
||||
("Relay Server", "中継サーバー"),
|
||||
("API Server", "APIサーバー"),
|
||||
("invalid_http", "http:// もしくは https:// から入力してください"),
|
||||
("Invalid IP", "無効なIP"),
|
||||
("id_change_tip", "使用できるのは大文字・小文字のアルファベット、数字、アンダースコア(_)のみです。初めの文字はアルファベットにする必要があります。6文字から16文字までです。"),
|
||||
("Invalid format", "無効な形式"),
|
||||
("server_not_support", "サーバー側でまだサポートされていません"),
|
||||
("Not available", "利用不可"),
|
||||
("Too frequent", "使用量が多すぎです"),
|
||||
("Cancel", "キャンセル"),
|
||||
("Skip", "スキップ"),
|
||||
("Close", "閉じる"),
|
||||
("Retry", "再試行"),
|
||||
("OK", "OK"),
|
||||
("Password Required", "パスワードが必要"),
|
||||
("Please enter your password", "パスワードを入力してください"),
|
||||
("Remember password", "パスワードを記憶する"),
|
||||
("Wrong Password", "パスワードが間違っています"),
|
||||
("Do you want to enter again?", "もう一度入力しますか?"),
|
||||
("Connection Error", "接続エラー"),
|
||||
("Error", "エラー"),
|
||||
("Reset by the peer", "相手がリセットしました"),
|
||||
("Connecting...", "接続中..."),
|
||||
("Connection in progress. Please wait.", "接続中です。しばらくお待ちください。"),
|
||||
("Please try 1 minute later", "1分後にもう一度お試しください"),
|
||||
("Login Error", "ログインエラー"),
|
||||
("Successful", "成功"),
|
||||
("Connected, waiting for image...", "接続完了、画像を取得中..."),
|
||||
("Name", "名前"),
|
||||
("Type", "種類"),
|
||||
("Modified", "最終更新"),
|
||||
("Size", "サイズ"),
|
||||
("Show Hidden Files", "隠しファイルを表示"),
|
||||
("Receive", "受信"),
|
||||
("Send", "送信"),
|
||||
("Refresh File", "ファイルを更新"),
|
||||
("Local", "ローカル"),
|
||||
("Remote", "リモート"),
|
||||
("Remote Computer", "リモート側コンピューター"),
|
||||
("Local Computer", "ローカル側コンピューター"),
|
||||
("Confirm Delete", "削除の確認"),
|
||||
("Delete", "削除"),
|
||||
("Properties", "プロパティ"),
|
||||
("Multi Select", "複数選択"),
|
||||
("Empty Directory", "空のディレクトリ"),
|
||||
("Not an empty directory", "空ではないディレクトリ"),
|
||||
("Are you sure you want to delete this file?", "本当にこのファイルを削除しますか?"),
|
||||
("Are you sure you want to delete this empty directory?", "本当にこの空のディレクトリを削除しますか?"),
|
||||
("Are you sure you want to delete the file of this directory?", "本当にこのディレクトリ内のファイルを削除しますか?"),
|
||||
("Do this for all conflicts", "他のすべてにも適用する"),
|
||||
("This is irreversible!", "この操作は元に戻せません!"),
|
||||
("Deleting", "削除中"),
|
||||
("files", "ファイル"),
|
||||
("Waiting", "待機中"),
|
||||
("Finished", "完了"),
|
||||
("Speed", "速度"),
|
||||
("Custom Image Quality", "画質を調整"),
|
||||
("Privacy mode", "プライバシーモード"),
|
||||
("Block user input", "ユーザーの入力をブロック"),
|
||||
("Unblock user input", "ユーザーの入力を許可"),
|
||||
("Adjust Window", "ウィンドウを調整"),
|
||||
("Original", "オリジナル"),
|
||||
("Shrink", "縮小"),
|
||||
("Stretch", "伸縮"),
|
||||
("Good image quality", "画質優先"),
|
||||
("Balanced", "バランス"),
|
||||
("Optimize reaction time", "速度優先"),
|
||||
("Custom", "カスタム"),
|
||||
("Show remote cursor", "リモート側のカーソルを表示"),
|
||||
("Show quality monitor", "品質モニターを表示"),
|
||||
("Disable clipboard", "クリップボードを無効化"),
|
||||
("Lock after session end", "セッション終了後にロックする"),
|
||||
("Insert", "送信"),
|
||||
("Insert Lock", "ロック命令を送信"),
|
||||
("Refresh", "更新"),
|
||||
("ID does not exist", "IDが存在しません"),
|
||||
("Failed to connect to rendezvous server", "ランデブーサーバーに接続できませんでした"),
|
||||
("Please try later", "後でもう一度お試しください"),
|
||||
("Remote desktop is offline", "リモート側デスクトップがオフラインです"),
|
||||
("Key mismatch", "キーが一致しません"),
|
||||
("Timeout", "タイムアウト"),
|
||||
("Failed to connect to relay server", "中継サーバーに接続できませんでした"),
|
||||
("Failed to connect via rendezvous server", "ランデブーサーバー経由で接続できませんでした"),
|
||||
("Failed to connect via relay server", "中継サーバー経由で接続できませんでした"),
|
||||
("Failed to make direct connection to remote desktop", "リモート側デスクトップと直接接続できませんでした"),
|
||||
("Set Password", "パスワードを設定"),
|
||||
("OS Password", "OSのパスワード"),
|
||||
("install_tip", "RustDeskがUACの影響によりリモート側で正常に動作しない場合があります。UACを回避するには、下のボタンをクリックしてシステムにRustDeskをインストールしてください。"),
|
||||
("Click to upgrade", "アップグレード"),
|
||||
("Click to download", "ダウンロード"),
|
||||
("Click to update", "アップデート"),
|
||||
("Configure", "設定"),
|
||||
("config_acc", "リモートからあなたのデスクトップを操作するには、RustDeskに「アクセシビリティ」権限を与える必要があります。"),
|
||||
("config_screen", "リモートからあなたのデスクトップにアクセスするには、RustDeskに「画面収録」権限を与える必要があります。"),
|
||||
("Installing ...", "インストール中..."),
|
||||
("Install", "インストール"),
|
||||
("Installation", "インストール"),
|
||||
("Installation Path", "インストール先のパス"),
|
||||
("Create start menu shortcuts", "スタートメニューにショートカットを作成する"),
|
||||
("Create desktop icon", "デスクトップにアイコンを作成する"),
|
||||
("agreement_tip", "インストールを開始することで、ライセンス条項に同意したとみなされます。"),
|
||||
("Accept and Install", "同意してインストール"),
|
||||
("End-user license agreement", "エンドユーザー ライセンス条項"),
|
||||
("Generating ...", "生成中 ..."),
|
||||
("Your installation is lower version.", "インストール済みのバージョンが古いです。"),
|
||||
("not_close_tcp_tip", "トンネルを使用中はこのウィンドウを閉じないでください"),
|
||||
("Listening ...", "リッスン中 ..."),
|
||||
("Remote Host", "リモートのホスト"),
|
||||
("Remote Port", "リモートのポート"),
|
||||
("Action", "操作"),
|
||||
("Add", "追加"),
|
||||
("Local Port", "ローカルのポート"),
|
||||
("setup_server_tip", "接続をより速くするには、自分のサーバーをセットアップしてください"),
|
||||
("Too short, at least 6 characters.", "短すぎます。最低6文字です。"),
|
||||
("The confirmation is not identical.", "確認用と一致しません。"),
|
||||
("Permissions", "権限"),
|
||||
("Accept", "承諾"),
|
||||
("Dismiss", "無視"),
|
||||
("Disconnect", "切断"),
|
||||
("Allow using keyboard and mouse", "キーボード・マウスの使用を許可"),
|
||||
("Allow using clipboard", "クリップボードの使用を許可"),
|
||||
("Allow hearing sound", "サウンドの受信を許可"),
|
||||
("Allow file copy and paste", "ファイルのコピーアンドペーストを許可"),
|
||||
("Connected", "接続済み"),
|
||||
("Direct and encrypted connection", "接続は暗号化され、直接つながっている"),
|
||||
("Relayed and encrypted connection", "接続は暗号化され、中継されている"),
|
||||
("Direct and unencrypted connection", "接続は暗号化されてなく、直接つながっている"),
|
||||
("Relayed and unencrypted connection", "接続は暗号化されてなく、中継されている"),
|
||||
("Enter Remote ID", "リモートのIDを入力"),
|
||||
("Enter your password", "パスワードを入力"),
|
||||
("Logging in...", "ログイン中..."),
|
||||
("Enable RDP session sharing", "RDPセッション共有を有効化"),
|
||||
("Auto Login", "自動ログイン"),
|
||||
("Enable Direct IP Access", "直接IPアクセスを有効化"),
|
||||
("Rename", "名前の変更"),
|
||||
("Space", "スペース"),
|
||||
("Create Desktop Shortcut", "デスクトップにショートカットを作成する"),
|
||||
("Change Path", "パスを変更"),
|
||||
("Create Folder", "フォルダを作成"),
|
||||
("Please enter the folder name", "フォルダ名を入力してください"),
|
||||
("Fix it", "修復"),
|
||||
("Warning", "注意"),
|
||||
("Login screen using Wayland is not supported", "Waylandを使用したログインスクリーンはサポートされていません"),
|
||||
("Reboot required", "再起動が必要"),
|
||||
("Unsupported display server ", "サポートされていないディスプレイサーバー"),
|
||||
("x11 expected", "X11 が必要です"),
|
||||
("Port", "ポート"),
|
||||
("Settings", "設定"),
|
||||
("Username", "ユーザー名"),
|
||||
("Invalid port", "無効なポート"),
|
||||
("Closed manually by the peer", "相手が手動で切断しました"),
|
||||
("Enable remote configuration modification", "リモート設定変更を有効化"),
|
||||
("Run without install", "インストールせずに実行"),
|
||||
("Always connected via relay", "常に中継サーバー経由で接続"),
|
||||
("Always connect via relay", "常に中継サーバー経由で接続"),
|
||||
("whitelist_tip", "ホワイトリストに登録されたIPからのみ接続を許可します"),
|
||||
("Login", "ログイン"),
|
||||
("Logout", "ログアウト"),
|
||||
("Tags", "タグ"),
|
||||
("Search ID", "IDを検索"),
|
||||
("Current Wayland display server is not supported", "現在のWaylandディスプレイサーバーはサポートされていません"),
|
||||
("whitelist_sep", "カンマやセミコロン、空白、改行で区切ってください"),
|
||||
("Add ID", "IDを追加"),
|
||||
("Add Tag", "タグを追加"),
|
||||
("Unselect all tags", "全てのタグを選択解除"),
|
||||
("Network error", "ネットワークエラー"),
|
||||
("Username missed", "ユーザー名がありません"),
|
||||
("Password missed", "パスワードがありません"),
|
||||
("Wrong credentials", "資格情報が間違っています"),
|
||||
("Edit Tag", "タグを編集"),
|
||||
("Unremember Password", "パスワードの記憶を解除"),
|
||||
("Favorites", "お気に入り"),
|
||||
("Add to Favorites", "お気に入りに追加"),
|
||||
("Remove from Favorites", "お気に入りから削除"),
|
||||
("Empty", "空"),
|
||||
("Invalid folder name", "無効なフォルダ名"),
|
||||
("Socks5 Proxy", "SOCKS5プロキシ"),
|
||||
("Hostname", "ホスト名"),
|
||||
("Discovered", "探知済み"),
|
||||
("install_daemon_tip", "起動時に開始するには、システムサービスをインストールする必要があります。"),
|
||||
("Remote ID", "リモートのID"),
|
||||
("Paste", "ペースト"),
|
||||
("Paste here?", "ここにペースト?"),
|
||||
("Are you sure to close the connection?", "本当に切断しますか?"),
|
||||
("Download new version", "新しいバージョンをダウンロード"),
|
||||
("Touch mode", "タッチモード"),
|
||||
("Mouse mode", "マウスモード"),
|
||||
("One-Finger Tap", "1本指でタップ"),
|
||||
("Left Mouse", "マウス左クリック"),
|
||||
("One-Long Tap", "1本指でロングタップ"),
|
||||
("Two-Finger Tap", "2本指でタップ"),
|
||||
("Right Mouse", "マウス右クリック"),
|
||||
("One-Finger Move", "1本指でドラッグ"),
|
||||
("Double Tap & Move", "2本指でタップ&ドラッグ"),
|
||||
("Mouse Drag", "マウスドラッグ"),
|
||||
("Three-Finger vertically", "3本指で縦方向"),
|
||||
("Mouse Wheel", "マウスホイール"),
|
||||
("Two-Finger Move", "2本指でドラッグ"),
|
||||
("Canvas Move", "キャンバスの移動"),
|
||||
("Pinch to Zoom", "ピンチしてズーム"),
|
||||
("Canvas Zoom", "キャンバスのズーム"),
|
||||
("Reset canvas", "キャンバスのリセット"),
|
||||
("No permission of file transfer", "ファイル転送の権限がありません"),
|
||||
("Note", "ノート"),
|
||||
("Connection", "接続"),
|
||||
("Share Screen", "画面を共有"),
|
||||
("CLOSE", "閉じる"),
|
||||
("OPEN", "開く"),
|
||||
("Chat", "チャット"),
|
||||
("Total", "計"),
|
||||
("items", "個のアイテム"),
|
||||
("Selected", "選択済み"),
|
||||
("Screen Capture", "画面キャプチャ"),
|
||||
("Input Control", "入力操作"),
|
||||
("Audio Capture", "音声キャプチャ"),
|
||||
("File Connection", "ファイルの接続"),
|
||||
("Screen Connection", "画面の接続"),
|
||||
("Do you accept?", "承諾しますか?"),
|
||||
("Open System Setting", "端末設定を開く"),
|
||||
("How to get Android input permission?", "Androidの入力権限を取得するには?"),
|
||||
("android_input_permission_tip1", "このAndroid端末をリモートの端末からマウスやタッチで操作するには、RustDeskに「アクセシビリティ」サービスの使用を許可する必要があります。"),
|
||||
("android_input_permission_tip2", "次の端末設定ページに進み、「インストール済みアプリ」から「RestDesk Input」をオンにしてください。"),
|
||||
("android_new_connection_tip", "新しい操作リクエストが届きました。この端末を操作しようとしています。"),
|
||||
("android_service_will_start_tip", "「画面キャプチャ」をオンにするとサービスが自動的に開始され、他の端末がこの端末への接続をリクエストできるようになります。"),
|
||||
("android_stop_service_tip", "サービスを停止すると、現在確立されている接続が全て自動的に閉じられます。"),
|
||||
("android_version_audio_tip", "現在のAndroidバージョンでは音声キャプチャはサポートされていません。Android 10以降にアップグレードしてください。"),
|
||||
("android_start_service_tip", "「サービスを開始」をタップするか「画面キャプチャ」を開くと、画面共有サービスが開始されます。"),
|
||||
("Account", "アカウント"),
|
||||
("Overwrite", "上書き"),
|
||||
("This file exists, skip or overwrite this file?", "このファイルは存在しています。スキップするか上書きしますか?"),
|
||||
("Quit", "終了"),
|
||||
("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"), // @TODO: Update url when someone translates the document
|
||||
("Help", "ヘルプ"),
|
||||
("Failed", "失敗"),
|
||||
("Succeeded", "成功"),
|
||||
("Someone turns on privacy mode, exit", "プライバシーモードがオンになりました。終了します。"),
|
||||
("Unsupported", "サポートされていません"),
|
||||
("Peer denied", "相手が拒否しました"),
|
||||
("Please install plugins", "プラグインをインストールしてください"),
|
||||
("Peer exit", "相手が終了しました"),
|
||||
("Failed to turn off", "オフにできませんでした"),
|
||||
("Turned off", "オフになりました"),
|
||||
("In privacy mode", "プライバシーモード開始"),
|
||||
("Out privacy mode", "プライバシーモード終了"),
|
||||
("Language", "言語"),
|
||||
("Keep RustDesk background service", "RustDesk バックグラウンドサービスを維持"),
|
||||
("Ignore Battery Optimizations", "バッテリーの最適化を無効にする"),
|
||||
("android_open_battery_optimizations_tip", "この機能を使わない場合は、次のRestDeskアプリ設定ページから「バッテリー」に進み、「制限なし」の選択を外してください"),
|
||||
("Connection not allowed", "接続が許可されていません"),
|
||||
("Use temporary password", "使い捨てのパスワードを使用"),
|
||||
("Use permanent password", "固定のパスワードを使用"),
|
||||
("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_restarting_tip", "リモート端末は再起動中です。このメッセージボックスを閉じて、しばらくした後に固定のパスワードを使用して再接続してください。"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
@@ -1099,8 +1099,9 @@ impl Connection {
|
||||
}
|
||||
Some(file_action::Union::Send(s)) => {
|
||||
let id = s.id;
|
||||
let od =
|
||||
can_enable_overwrite_detection(get_version_number(VERSION));
|
||||
let od = can_enable_overwrite_detection(get_version_number(
|
||||
&self.lr.version,
|
||||
));
|
||||
let path = s.path.clone();
|
||||
match fs::TransferJob::new_read(
|
||||
id,
|
||||
@@ -1123,6 +1124,11 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
Some(file_action::Union::Receive(r)) => {
|
||||
// note: 1.1.10 introduced identical file detection, which breaks original logic of send/recv files
|
||||
// whenever got send/recv request, check peer version to ensure old version of rustdesk
|
||||
let od = can_enable_overwrite_detection(get_version_number(
|
||||
&self.lr.version,
|
||||
));
|
||||
self.send_fs(ipc::FS::NewWrite {
|
||||
path: r.path,
|
||||
id: r.id,
|
||||
@@ -1133,6 +1139,7 @@ impl Connection {
|
||||
.drain(..)
|
||||
.map(|f| (f.name, f.modified_time))
|
||||
.collect(),
|
||||
overwrite_detection: od,
|
||||
});
|
||||
}
|
||||
Some(file_action::Union::RemoveDir(d)) => {
|
||||
|
||||
@@ -160,8 +160,8 @@ impl ConnectionManager {
|
||||
id,
|
||||
file_num,
|
||||
mut files,
|
||||
overwrite_detection
|
||||
} => {
|
||||
let od = can_enable_overwrite_detection(get_version_number(VERSION));
|
||||
// cm has no show_hidden context
|
||||
// dummy remote, show_hidden, is_remote
|
||||
write_jobs.push(fs::TransferJob::new_write(
|
||||
@@ -179,7 +179,7 @@ impl ConnectionManager {
|
||||
..Default::default()
|
||||
})
|
||||
.collect(),
|
||||
od,
|
||||
overwrite_detection,
|
||||
));
|
||||
}
|
||||
ipc::FS::CancelWrite { id } => {
|
||||
|
||||
@@ -23,10 +23,6 @@ use clipboard::{
|
||||
get_rx_clip_client, server_clip_file,
|
||||
};
|
||||
use enigo::{self, Enigo, KeyboardControllable};
|
||||
use hbb_common::fs::{
|
||||
can_enable_overwrite_detection, get_job, get_string, new_send_confirm, DigestCheckResult,
|
||||
RemoveJobMeta,
|
||||
};
|
||||
use hbb_common::{
|
||||
allow_err,
|
||||
config::{Config, LocalConfig, PeerConfig},
|
||||
@@ -43,6 +39,13 @@ use hbb_common::{
|
||||
Stream,
|
||||
};
|
||||
use hbb_common::{config::TransferSerde, fs::TransferJobMeta};
|
||||
use hbb_common::{
|
||||
fs::{
|
||||
can_enable_overwrite_detection, get_job, get_string, new_send_confirm, DigestCheckResult,
|
||||
RemoveJobMeta,
|
||||
},
|
||||
get_version_number,
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
use crate::clipboard_file::*;
|
||||
@@ -239,15 +242,6 @@ impl sciter::EventHandler for Handler {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct QualityStatus {
|
||||
speed: Option<String>,
|
||||
fps: Option<i32>,
|
||||
delay: Option<i32>,
|
||||
target_bitrate: Option<i32>,
|
||||
codec_format: Option<CodecFormat>,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
pub fn new(cmd: String, id: String, password: String, args: Vec<String>) -> Self {
|
||||
let me = Self {
|
||||
@@ -638,8 +632,9 @@ impl Handler {
|
||||
}
|
||||
|
||||
fn restart_remote_device(&mut self) {
|
||||
self.lc.write().unwrap().restarting_remote_device = true;
|
||||
let msg = self.lc.write().unwrap().restart_remote_device();
|
||||
let mut lc = self.lc.write().unwrap();
|
||||
lc.restarting_remote_device = true;
|
||||
let msg = lc.restart_remote_device();
|
||||
self.send(Data::Message(msg));
|
||||
}
|
||||
|
||||
@@ -2076,6 +2071,22 @@ impl Remote {
|
||||
true
|
||||
}
|
||||
|
||||
async fn send_opts_after_login(&self, peer: &mut Stream) {
|
||||
if let Some(opts) = self
|
||||
.handler
|
||||
.lc
|
||||
.read()
|
||||
.unwrap()
|
||||
.get_option_message_after_login()
|
||||
{
|
||||
let mut misc = Misc::new();
|
||||
misc.set_option(opts);
|
||||
let mut msg_out = Message::new();
|
||||
msg_out.set_misc(misc);
|
||||
allow_err!(peer.send(&msg_out).await);
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_msg_from_peer(&mut self, data: &[u8], peer: &mut Stream) -> bool {
|
||||
if let Ok(msg_in) = Message::parse_from_bytes(&data) {
|
||||
match msg_in.union {
|
||||
@@ -2084,6 +2095,7 @@ impl Remote {
|
||||
self.first_frame = true;
|
||||
self.handler.call2("closeSuccess", &make_args!());
|
||||
self.handler.call("adaptSize", &make_args!());
|
||||
self.send_opts_after_login(peer).await;
|
||||
}
|
||||
let incomming_format = CodecFormat::from(&vf);
|
||||
if self.video_format != incomming_format {
|
||||
@@ -2595,6 +2607,9 @@ impl Interface for Handler {
|
||||
pi_sciter.set_item("hostname", pi.hostname.clone());
|
||||
pi_sciter.set_item("platform", pi.platform.clone());
|
||||
pi_sciter.set_item("sas_enabled", pi.sas_enabled);
|
||||
if get_version_number(&pi.version) < get_version_number("1.1.10") {
|
||||
self.call2("setPermission", &make_args!("restart", false));
|
||||
}
|
||||
if self.is_file_transfer() {
|
||||
if pi.username.is_empty() {
|
||||
self.on_error("No active console user logged on, please connect and logon first.");
|
||||
|
||||
Reference in New Issue
Block a user