diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index a59c3c722..0d9c131e6 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -38,7 +38,7 @@ env: # https://github.com/rustdesk/rustdesk/actions/runs/14414119794/job/40427970174 # 2. Update the `VCPKG_COMMIT_ID` in `ci.yml` and `playground.yml`. VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" - VERSION: "1.4.1" + VERSION: "1.4.2" NDK_VERSION: "r27c" #signing keys env variable checks ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}" diff --git a/.github/workflows/playground.yml b/.github/workflows/playground.yml index 53e7f642f..41f284dd5 100644 --- a/.github/workflows/playground.yml +++ b/.github/workflows/playground.yml @@ -17,7 +17,7 @@ env: TAG_NAME: "nightly" VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" - VERSION: "1.4.1" + VERSION: "1.4.2" NDK_VERSION: "r26d" #signing keys env variable checks ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}" diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index 2b1bff105..24bc193c4 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -10,6 +10,6 @@ jobs: - uses: vedantmgoyal9/winget-releaser@main with: identifier: RustDesk.RustDesk - version: "1.4.1" - release-tag: "1.4.1" + version: "1.4.2" + release-tag: "1.4.2" token: ${{ secrets.WINGET_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index 7487b5c52..551cbf050 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6110,7 +6110,7 @@ dependencies = [ [[package]] name = "rustdesk" -version = "1.4.1" +version = "1.4.2" dependencies = [ "android-wakelock", "android_logger", @@ -6216,7 +6216,7 @@ dependencies = [ [[package]] name = "rustdesk-portable-packer" -version = "1.4.1" +version = "1.4.2" dependencies = [ "brotli", "dirs 5.0.1", diff --git a/Cargo.toml b/Cargo.toml index d8403e143..fcc270a39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustdesk" -version = "1.4.1" +version = "1.4.2" authors = ["rustdesk "] edition = "2021" build= "build.rs" diff --git a/appimage/AppImageBuilder-aarch64.yml b/appimage/AppImageBuilder-aarch64.yml index c7b8cfee1..2f42cb739 100644 --- a/appimage/AppImageBuilder-aarch64.yml +++ b/appimage/AppImageBuilder-aarch64.yml @@ -18,7 +18,7 @@ AppDir: id: rustdesk name: rustdesk icon: rustdesk - version: 1.4.1 + version: 1.4.2 exec: usr/share/rustdesk/rustdesk exec_args: $@ apt: diff --git a/appimage/AppImageBuilder-x86_64.yml b/appimage/AppImageBuilder-x86_64.yml index 4025f1669..40451fce0 100644 --- a/appimage/AppImageBuilder-x86_64.yml +++ b/appimage/AppImageBuilder-x86_64.yml @@ -18,7 +18,7 @@ AppDir: id: rustdesk name: rustdesk icon: rustdesk - version: 1.4.1 + version: 1.4.2 exec: usr/share/rustdesk/rustdesk exec_args: $@ apt: diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index d8e1aff2c..9172703e7 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # 1.1.9-1 works for android, but for ios it becomes 1.1.91, need to set it to 1.1.9-a.1 for iOS, will get 1.1.9.1, but iOS store not allow 4 numbers -version: 1.4.1+59 +version: 1.4.2+60 environment: sdk: '^3.1.0' diff --git a/libs/hbb_common b/libs/hbb_common index 57c8a23ab..024380d0f 160000 --- a/libs/hbb_common +++ b/libs/hbb_common @@ -1 +1 @@ -Subproject commit 57c8a23ab970587ea6380943b04dc354020bbe7c +Subproject commit 024380d0f9f904e9b4371c416ad5056bcd151b77 diff --git a/libs/portable/Cargo.toml b/libs/portable/Cargo.toml index 8802ab306..8bccf68ec 100644 --- a/libs/portable/Cargo.toml +++ b/libs/portable/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustdesk-portable-packer" -version = "1.4.1" +version = "1.4.2" edition = "2021" description = "RustDesk Remote Desktop" diff --git a/res/PKGBUILD b/res/PKGBUILD index 269ded858..56254c044 100644 --- a/res/PKGBUILD +++ b/res/PKGBUILD @@ -1,5 +1,5 @@ pkgname=rustdesk -pkgver=1.4.1 +pkgver=1.4.2 pkgrel=0 epoch= pkgdesc="" diff --git a/res/rpm-flutter-suse.spec b/res/rpm-flutter-suse.spec index dd6b42c16..3f096e496 100644 --- a/res/rpm-flutter-suse.spec +++ b/res/rpm-flutter-suse.spec @@ -1,5 +1,5 @@ Name: rustdesk -Version: 1.4.1 +Version: 1.4.2 Release: 0 Summary: RPM package License: GPL-3.0 diff --git a/res/rpm-flutter.spec b/res/rpm-flutter.spec index b461507da..2762dbb18 100644 --- a/res/rpm-flutter.spec +++ b/res/rpm-flutter.spec @@ -1,5 +1,5 @@ Name: rustdesk -Version: 1.4.1 +Version: 1.4.2 Release: 0 Summary: RPM package License: GPL-3.0 diff --git a/res/rpm.spec b/res/rpm.spec index a51646631..d61014d2e 100644 --- a/res/rpm.spec +++ b/res/rpm.spec @@ -1,5 +1,5 @@ Name: rustdesk -Version: 1.4.1 +Version: 1.4.2 Release: 0 Summary: RPM package License: GPL-3.0 diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 3b07525fb..7b0e73410 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -704,6 +704,7 @@ impl Remote { if is_remote { if let Some(job) = get_job(id, &mut self.write_jobs) { job.is_last_job = false; + job.is_resume = true; allow_err!( peer.send(&fs::new_send( id, @@ -718,12 +719,13 @@ impl Remote { } else { if let Some(job) = get_job(id, &mut self.read_jobs) { match &job.data_source { - fs::DataSource::FilePath(p) => { + fs::DataSource::FilePath(_p) => { job.is_last_job = false; + job.is_resume = true; allow_err!( peer.send(&fs::new_receive( id, - p.to_string_lossy().to_string(), + job.remote.clone(), job.file_num, job.files.clone(), job.total_size(), @@ -771,7 +773,8 @@ impl Remote { Some(file_transfer_send_confirm_request::Union::Skip(true)) }, ..Default::default() - }); + }) + .await; } } else { if let Some(job) = fs::get_job(id, &mut self.write_jobs) { @@ -790,7 +793,7 @@ impl Remote { }, ..Default::default() }; - job.confirm(&req); + job.confirm(&req).await; file_action.set_send_confirm(req); msg.set_file_action(file_action); allow_err!(peer.send(&msg).await); @@ -1471,14 +1474,21 @@ impl Remote { if let fs::DataSource::FilePath(p) = &job.data_source { let read_path = get_string(&fs::TransferJob::join(p, &file.name)); - let overwrite_strategy = + let mut overwrite_strategy = job.default_overwrite_strategy(); + let mut offset = 0; + if digest.is_identical && job.is_resume { + if digest.transferred_size > 0 { + overwrite_strategy = Some(true); + offset = digest.transferred_size as _; + } + } 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) + file_transfer_send_confirm_request::Union::OffsetBlk(offset) } else { file_transfer_send_confirm_request::Union::Skip( true, @@ -1486,7 +1496,7 @@ impl Remote { }), ..Default::default() }; - job.confirm(&req); + job.confirm(&req).await; let msg = new_send_confirm(req); allow_err!(peer.send(&msg).await); } else { @@ -1507,25 +1517,40 @@ impl Remote { if let fs::DataSource::FilePath(p) = &job.data_source { let write_path = get_string(&fs::TransferJob::join(p, &file.name)); - let overwrite_strategy = - job.default_overwrite_strategy(); + job.set_digest(digest.file_size, digest.last_modified); + let peer_ver = self.handler.lc.read().unwrap().version; + let is_support_resume = + crate::is_support_file_transfer_resume_num( + peer_ver, + ); match fs::is_write_need_confirmation( + is_support_resume && job.is_resume, &write_path, &digest, ) { Ok(res) => match res { DigestCheckResult::IsSame => { let req = FileTransferSendConfirmRequest { - id: digest.id, - file_num: digest.file_num, - union: Some(file_transfer_send_confirm_request::Union::Skip(true)), - ..Default::default() - }; - job.confirm(&req); + id: digest.id, + file_num: digest.file_num, + union: Some(file_transfer_send_confirm_request::Union::Skip(true)), + ..Default::default() + }; + job.confirm(&req).await; let msg = new_send_confirm(req); allow_err!(peer.send(&msg).await); } DigestCheckResult::NeedConfirm(digest) => { + let mut overwrite_strategy = + job.default_overwrite_strategy(); + let mut offset = 0; + if digest.is_identical + && job.is_resume + && digest.transferred_size > 0 + { + overwrite_strategy = Some(true); + offset = digest.transferred_size as _; + } if let Some(overwrite) = overwrite_strategy { let req = @@ -1533,13 +1558,13 @@ impl Remote { id: digest.id, file_num: digest.file_num, union: Some(if overwrite { - file_transfer_send_confirm_request::Union::OffsetBlk(0) + file_transfer_send_confirm_request::Union::OffsetBlk(offset) } else { file_transfer_send_confirm_request::Union::Skip(true) }), ..Default::default() }; - job.confirm(&req); + job.confirm(&req).await; let msg = new_send_confirm(req); allow_err!(peer.send(&msg).await); } else { @@ -1559,7 +1584,7 @@ impl Remote { union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)), ..Default::default() }; - job.confirm(&req); + job.confirm(&req).await; let msg = new_send_confirm(req); allow_err!(peer.send(&msg).await); } @@ -1906,7 +1931,7 @@ impl Remote { }, Some(file_action::Union::SendConfirm(c)) => { if let Some(job) = fs::get_job(c.id, &mut self.read_jobs) { - job.confirm(&c); + job.confirm(&c).await; } } _ => {} diff --git a/src/common.rs b/src/common.rs index 1fe13cd28..ca2ed3cac 100644 --- a/src/common.rs +++ b/src/common.rs @@ -163,6 +163,16 @@ pub fn is_support_screenshot_num(ver: i64) -> bool { ver >= hbb_common::get_version_number("1.4.0") } +#[inline] +pub fn is_support_file_transfer_resume(ver: &str) -> bool { + is_support_file_transfer_resume_num(hbb_common::get_version_number(ver)) +} + +#[inline] +pub fn is_support_file_transfer_resume_num(ver: i64) -> bool { + ver >= hbb_common::get_version_number("1.4.2") +} + // is server process, with "--server" args #[inline] pub fn is_server() -> bool { diff --git a/src/ipc.rs b/src/ipc.rs index 1ae048162..98db30eb1 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -104,7 +104,9 @@ pub enum FS { file_size: u64, last_modified: u64, is_upload: bool, + is_resume: bool, }, + SendConfirm(Vec), Rename { id: i32, path: String, diff --git a/src/server/connection.rs b/src/server/connection.rs index ebc1d878b..5b1302b6a 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2705,7 +2705,11 @@ impl Connection { } Some(file_action::Union::SendConfirm(r)) => { if let Some(job) = fs::get_job(r.id, &mut self.read_jobs) { - job.confirm(&r); + job.confirm(&r).await; + } else { + if let Ok(sc) = r.write_to_bytes() { + self.send_fs(ipc::FS::SendConfirm(sc)); + } } } Some(file_action::Union::Rename(r)) => { @@ -2749,6 +2753,7 @@ impl Connection { file_size: d.file_size, last_modified: d.last_modified, is_upload: true, + is_resume: d.is_resume, }), Some(file_response::Union::Error(e)) => { self.send_fs(ipc::FS::WriteError { diff --git a/src/ui_cm_interface.rs b/src/ui_cm_interface.rs index 8264cbdba..959187cb9 100644 --- a/src/ui_cm_interface.rs +++ b/src/ui_cm_interface.rs @@ -861,6 +861,7 @@ async fn handle_fs( file_size, last_modified, is_upload, + is_resume, } => { if let Some(job) = fs::get_job(id, write_jobs) { let mut req = FileTransferSendConfirmRequest { @@ -879,8 +880,9 @@ async fn handle_fs( if let Some(file) = job.files().get(file_num as usize) { if let fs::DataSource::FilePath(p) = &job.data_source { let path = get_string(&fs::TransferJob::join(p, &file.name)); - match is_write_need_confirmation(&path, &digest) { + match is_write_need_confirmation(is_resume, &path, &digest) { Ok(digest_result) => { + job.set_digest(file_size, last_modified); match digest_result { DigestCheckResult::IsSame => { req.set_skip(true); @@ -910,6 +912,13 @@ async fn handle_fs( } } } + ipc::FS::SendConfirm(bytes) => { + if let Ok(r) = FileTransferSendConfirmRequest::parse_from_bytes(&bytes) { + if let Some(job) = fs::get_job(r.id, write_jobs) { + job.confirm(&r).await; + } + } + } ipc::FS::Rename { id, path, new_name } => { rename_file(path, new_name, id, tx).await; }