mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
commit
7c23b697de
24
.github/workflows/flutter-ci.yml
vendored
24
.github/workflows/flutter-ci.yml
vendored
@ -70,12 +70,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install flutter rust bridge deps
|
- name: Install flutter rust bridge deps
|
||||||
run: |
|
run: |
|
||||||
dart pub global activate ffigen --version 5.0.1
|
cargo install flutter_rust_bridge_codegen
|
||||||
$exists = Test-Path ~/.cargo/bin/flutter_rust_bridge_codegen.exe
|
|
||||||
Push-Location ..
|
|
||||||
git clone https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge --depth=1
|
|
||||||
Push-Location flutter_rust_bridge/frb_codegen ; cargo install --path . ; Pop-Location
|
|
||||||
Pop-Location
|
|
||||||
Push-Location flutter ; flutter pub get ; Pop-Location
|
Push-Location flutter ; flutter pub get ; Pop-Location
|
||||||
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
||||||
|
|
||||||
@ -134,14 +129,7 @@ jobs:
|
|||||||
- name: Install flutter rust bridge deps
|
- name: Install flutter rust bridge deps
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
dart pub global activate ffigen --version 5.0.1
|
cargo install flutter_rust_bridge_codegen
|
||||||
# flutter_rust_bridge
|
|
||||||
pushd /tmp
|
|
||||||
wget https://github.com/Kingtous/flutter_rust_bridge/releases/download/1.32.0-rustdesk/flutter_rust_bridge_codegen-x86_64-darwin.tgz
|
|
||||||
tar -zxvf flutter_rust_bridge_codegen-x86_64-darwin.tgz
|
|
||||||
mkdir -p ~/.cargo/bin
|
|
||||||
mv flutter_rust_bridge_codegen ~/.cargo/bin; chmod +x ~/.cargo/bin/flutter_rust_bridge_codegen
|
|
||||||
popd
|
|
||||||
pushd flutter && flutter pub get && popd
|
pushd flutter && flutter pub get && popd
|
||||||
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
||||||
|
|
||||||
@ -307,15 +295,10 @@ jobs:
|
|||||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Install ffigen
|
|
||||||
run: |
|
|
||||||
dart pub global activate ffigen --version 5.0.1
|
|
||||||
|
|
||||||
- name: Install flutter rust bridge deps
|
- name: Install flutter rust bridge deps
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
pushd /tmp && git clone https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge --depth=1 || true && popd
|
cargo install flutter_rust_bridge_codegen
|
||||||
pushd /tmp/flutter_rust_bridge/frb_codegen && cargo install --path . && popd
|
|
||||||
pushd flutter && flutter pub get && popd
|
pushd flutter && flutter pub get && popd
|
||||||
|
|
||||||
- name: Run flutter rust bridge
|
- name: Run flutter rust bridge
|
||||||
@ -328,6 +311,7 @@ jobs:
|
|||||||
name: bridge-artifact
|
name: bridge-artifact
|
||||||
path: |
|
path: |
|
||||||
./src/bridge_generated.rs
|
./src/bridge_generated.rs
|
||||||
|
./src/bridge_generated.io.rs
|
||||||
./flutter/lib/generated_bridge.dart
|
./flutter/lib/generated_bridge.dart
|
||||||
./flutter/lib/generated_bridge.freezed.dart
|
./flutter/lib/generated_bridge.freezed.dart
|
||||||
|
|
||||||
|
|||||||
24
.github/workflows/flutter-nightly.yml
vendored
24
.github/workflows/flutter-nightly.yml
vendored
@ -72,12 +72,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install flutter rust bridge deps
|
- name: Install flutter rust bridge deps
|
||||||
run: |
|
run: |
|
||||||
dart pub global activate ffigen --version 5.0.1
|
cargo install flutter_rust_bridge_codegen
|
||||||
$exists = Test-Path ~/.cargo/bin/flutter_rust_bridge_codegen.exe
|
|
||||||
Push-Location ..
|
|
||||||
git clone https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge --depth=1
|
|
||||||
Push-Location flutter_rust_bridge/frb_codegen ; cargo install --path . ; Pop-Location
|
|
||||||
Pop-Location
|
|
||||||
Push-Location flutter ; flutter pub get ; Pop-Location
|
Push-Location flutter ; flutter pub get ; Pop-Location
|
||||||
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
||||||
|
|
||||||
@ -213,14 +208,7 @@ jobs:
|
|||||||
- name: Install flutter rust bridge deps
|
- name: Install flutter rust bridge deps
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
dart pub global activate ffigen --version 5.0.1
|
cargo install flutter_rust_bridge_codegen
|
||||||
# flutter_rust_bridge
|
|
||||||
pushd /tmp
|
|
||||||
wget https://github.com/Kingtous/flutter_rust_bridge/releases/download/1.32.0-rustdesk/flutter_rust_bridge_codegen-x86_64-darwin.tgz
|
|
||||||
tar -zxvf flutter_rust_bridge_codegen-x86_64-darwin.tgz
|
|
||||||
mkdir -p ~/.cargo/bin
|
|
||||||
mv flutter_rust_bridge_codegen ~/.cargo/bin; chmod +x ~/.cargo/bin/flutter_rust_bridge_codegen
|
|
||||||
popd
|
|
||||||
pushd flutter && flutter pub get && popd
|
pushd flutter && flutter pub get && popd
|
||||||
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
|
||||||
|
|
||||||
@ -414,15 +402,10 @@ jobs:
|
|||||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Install ffigen
|
|
||||||
run: |
|
|
||||||
dart pub global activate ffigen --version 5.0.1
|
|
||||||
|
|
||||||
- name: Install flutter rust bridge deps
|
- name: Install flutter rust bridge deps
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
pushd /tmp && git clone https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge --depth=1 || true && popd
|
cargo install flutter_rust_bridge_codegen
|
||||||
pushd /tmp/flutter_rust_bridge/frb_codegen && cargo install --path . && popd
|
|
||||||
pushd flutter && flutter pub get && popd
|
pushd flutter && flutter pub get && popd
|
||||||
|
|
||||||
- name: Run flutter rust bridge
|
- name: Run flutter rust bridge
|
||||||
@ -435,6 +418,7 @@ jobs:
|
|||||||
name: bridge-artifact
|
name: bridge-artifact
|
||||||
path: |
|
path: |
|
||||||
./src/bridge_generated.rs
|
./src/bridge_generated.rs
|
||||||
|
./src/bridge_generated.io.rs
|
||||||
./flutter/lib/generated_bridge.dart
|
./flutter/lib/generated_bridge.dart
|
||||||
./flutter/lib/generated_bridge.freezed.dart
|
./flutter/lib/generated_bridge.freezed.dart
|
||||||
|
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,6 +19,7 @@ cert.pfx
|
|||||||
sciter.dll
|
sciter.dll
|
||||||
**pdb
|
**pdb
|
||||||
src/bridge_generated.rs
|
src/bridge_generated.rs
|
||||||
|
src/bridge_generated.io.rs
|
||||||
*deb
|
*deb
|
||||||
rustdesk
|
rustdesk
|
||||||
*.cache
|
*.cache
|
||||||
|
|||||||
121
Cargo.lock
generated
121
Cargo.lock
generated
@ -45,11 +45,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allo-isolate"
|
name = "allo-isolate"
|
||||||
version = "0.1.13"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccb993621e6bf1b67591005b0adad126159a0ab31af379743906158aed5330d0"
|
checksum = "8ed55848be9f41d44c79df6045b680a74a78bc579e0813f7f196cd7928e22fb1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"atomic",
|
"atomic",
|
||||||
|
"chrono",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -471,6 +473,12 @@ dependencies = [
|
|||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "build-target"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.11.1"
|
version = "3.11.1"
|
||||||
@ -565,9 +573,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cbindgen"
|
name = "cbindgen"
|
||||||
version = "0.23.0"
|
version = "0.24.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b6d248e3ca02f3fbfabcb9284464c596baec223a26d91bbf44a5a62ddb0d900"
|
checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 3.2.23",
|
"clap 3.2.23",
|
||||||
"heck 0.4.0",
|
"heck 0.4.0",
|
||||||
@ -838,6 +846,16 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console_error_panic_hook"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -1335,6 +1353,17 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "delegate"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "082a24a9967533dc5d743c602157637116fc1b52806d694a5a45e6f32567fcdd"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derivative"
|
name = "derivative"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
@ -1672,6 +1701,18 @@ version = "2.5.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "extend"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c5216e387a76eebaaf11f6d871ec8a4aae0b25f05456ee21f228e024b1b3610"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "failure"
|
name = "failure"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
@ -1744,28 +1785,44 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flutter_rust_bridge"
|
name = "flutter_rust_bridge"
|
||||||
version = "1.32.0"
|
version = "1.61.1"
|
||||||
source = "git+https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge#e5adce55eea0b74d3680e66a2c5252edf17b07e1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8079119bbe8fb63d7ebb731fa2aa68c6c8375f4ac95ca26d5868e64c0f4b9244"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allo-isolate",
|
"allo-isolate",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"build-target",
|
||||||
|
"bytemuck",
|
||||||
|
"cc",
|
||||||
|
"chrono",
|
||||||
|
"console_error_panic_hook",
|
||||||
"flutter_rust_bridge_macros",
|
"flutter_rust_bridge_macros",
|
||||||
|
"js-sys",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
"threadpool",
|
"threadpool",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flutter_rust_bridge_codegen"
|
name = "flutter_rust_bridge_codegen"
|
||||||
version = "1.32.0"
|
version = "1.61.1"
|
||||||
source = "git+https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge#e5adce55eea0b74d3680e66a2c5252edf17b07e1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efd7396bc479eae8aa24243e4c0e3d3dbda1909134f8de6bde4f080d262c9a0d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
"cbindgen",
|
"cbindgen",
|
||||||
|
"clap 3.2.23",
|
||||||
"convert_case",
|
"convert_case",
|
||||||
|
"delegate",
|
||||||
"enum_dispatch",
|
"enum_dispatch",
|
||||||
"env_logger 0.9.3",
|
"env_logger 0.9.3",
|
||||||
|
"extend",
|
||||||
|
"itertools 0.10.5",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
@ -1773,17 +1830,18 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"serde 1.0.149",
|
"serde 1.0.149",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"structopt",
|
|
||||||
"syn",
|
"syn",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml",
|
"toml",
|
||||||
|
"topological-sort",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flutter_rust_bridge_macros"
|
name = "flutter_rust_bridge_macros"
|
||||||
version = "1.32.0"
|
version = "1.61.1"
|
||||||
source = "git+https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge#e5adce55eea0b74d3680e66a2c5252edf17b07e1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d5cd827645690ef378be57a890d0581e17c28d07b712872af7d744f454fd27d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
@ -2164,7 +2222,7 @@ checksum = "41486a26d1366a8032b160b59065a59fb528530a46a49f627e7048fb8c064039"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"heck 0.3.3",
|
"heck 0.3.3",
|
||||||
"itertools",
|
"itertools 0.9.0",
|
||||||
"proc-macro-crate 0.1.5",
|
"proc-macro-crate 0.1.5",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -2798,6 +2856,15 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
@ -5150,30 +5217,6 @@ version = "0.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "structopt"
|
|
||||||
version = "0.3.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
|
||||||
dependencies = [
|
|
||||||
"clap 2.34.0",
|
|
||||||
"lazy_static",
|
|
||||||
"structopt-derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "structopt-derive"
|
|
||||||
version = "0.4.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
|
||||||
dependencies = [
|
|
||||||
"heck 0.3.3",
|
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
@ -5564,6 +5607,12 @@ dependencies = [
|
|||||||
"serde 1.0.149",
|
"serde 1.0.149",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "topological-sort"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
|||||||
@ -61,7 +61,7 @@ num_cpus = "1.13"
|
|||||||
bytes = { version = "1.2", features = ["serde"] }
|
bytes = { version = "1.2", features = ["serde"] }
|
||||||
default-net = { git = "https://github.com/Kingtous/default-net" }
|
default-net = { git = "https://github.com/Kingtous/default-net" }
|
||||||
wol-rs = "0.9.1"
|
wol-rs = "0.9.1"
|
||||||
flutter_rust_bridge = { git = "https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge", optional = true }
|
flutter_rust_bridge = { version = "1.61.1", optional = true }
|
||||||
errno = "0.2.8"
|
errno = "0.2.8"
|
||||||
rdev = { git = "https://github.com/fufesou/rdev" }
|
rdev = { git = "https://github.com/fufesou/rdev" }
|
||||||
url = { version = "2.1", features = ["serde"] }
|
url = { version = "2.1", features = ["serde"] }
|
||||||
@ -126,7 +126,7 @@ android_logger = "0.11"
|
|||||||
jni = "0.19"
|
jni = "0.19"
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
|
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
|
||||||
flutter_rust_bridge = { git = "https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge" }
|
flutter_rust_bridge = "1.61.1"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/simple_rc", "libs/portable"]
|
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/simple_rc", "libs/portable"]
|
||||||
@ -144,7 +144,7 @@ winapi = { version = "0.3", features = [ "winnt" ] }
|
|||||||
cc = "1.0"
|
cc = "1.0"
|
||||||
hbb_common = { path = "libs/hbb_common" }
|
hbb_common = { path = "libs/hbb_common" }
|
||||||
simple_rc = { path = "libs/simple_rc", optional = true }
|
simple_rc = { path = "libs/simple_rc", optional = true }
|
||||||
flutter_rust_bridge_codegen = { git = "https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge" }
|
flutter_rust_bridge_codegen = "1.61.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hound = "3.5"
|
hound = "3.5"
|
||||||
|
|||||||
23
build.rs
23
build.rs
@ -85,26 +85,35 @@ fn install_oboe() {
|
|||||||
|
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
fn gen_flutter_rust_bridge() {
|
fn gen_flutter_rust_bridge() {
|
||||||
|
use lib_flutter_rust_bridge_codegen::{
|
||||||
|
config_parse, frb_codegen, get_symbols_if_no_duplicates, RawOpts,
|
||||||
|
};
|
||||||
let llvm_path = match std::env::var("LLVM_HOME") {
|
let llvm_path = match std::env::var("LLVM_HOME") {
|
||||||
Ok(path) => Some(vec![path]),
|
Ok(path) => Some(vec![path]),
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
};
|
};
|
||||||
// Tell Cargo that if the given file changes, to rerun this build script.
|
// Tell Cargo that if the given file changes, to rerun this build script.
|
||||||
println!("cargo:rerun-if-changed=src/flutter_ffi.rs");
|
println!("cargo:rerun-if-changed=src/flutter_ffi.rs");
|
||||||
// settings for fbr_codegen
|
// Options for frb_codegen
|
||||||
let opts = lib_flutter_rust_bridge_codegen::Opts {
|
let raw_opts = RawOpts {
|
||||||
// Path of input Rust code
|
// Path of input Rust code
|
||||||
rust_input: "src/flutter_ffi.rs".to_string(),
|
rust_input: vec!["src/flutter_ffi.rs".to_string()],
|
||||||
// Path of output generated Dart code
|
// Path of output generated Dart code
|
||||||
dart_output: "flutter/lib/generated_bridge.dart".to_string(),
|
dart_output: vec!["flutter/lib/generated_bridge.dart".to_string()],
|
||||||
// Path of output generated C header
|
// Path of output generated C header
|
||||||
c_output: Some(vec!["flutter/macos/Runner/bridge_generated.h".to_string()]),
|
c_output: Some(vec!["flutter/macos/Runner/bridge_generated.h".to_string()]),
|
||||||
// for other options lets use default
|
/// Path to the installed LLVM
|
||||||
llvm_path,
|
llvm_path,
|
||||||
|
// for other options use defaults
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
// run fbr_codegen
|
// get opts from raw opts
|
||||||
lib_flutter_rust_bridge_codegen::frb_codegen(opts).unwrap();
|
let configs = config_parse(raw_opts);
|
||||||
|
// generation of rust api for ffi
|
||||||
|
let all_symbols = get_symbols_if_no_duplicates(&configs).unwrap();
|
||||||
|
for config in configs.iter() {
|
||||||
|
frb_codegen(config, &all_symbols).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@ -1261,23 +1261,28 @@ StreamSubscription? listenUniLinks() {
|
|||||||
|
|
||||||
/// Returns true if we successfully handle the startup arguments.
|
/// Returns true if we successfully handle the startup arguments.
|
||||||
bool checkArguments() {
|
bool checkArguments() {
|
||||||
|
// bootArgs:[--connect, 362587269, --switch_uuid, e3d531cc-5dce-41e0-bd06-5d4a2b1eec05]
|
||||||
// check connect args
|
// check connect args
|
||||||
final connectIndex = bootArgs.indexOf("--connect");
|
final connectIndex = bootArgs.indexOf("--connect");
|
||||||
if (connectIndex == -1) {
|
if (connectIndex == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String? arg =
|
String? id =
|
||||||
bootArgs.length < connectIndex + 1 ? null : bootArgs[connectIndex + 1];
|
bootArgs.length < connectIndex + 1 ? null : bootArgs[connectIndex + 1];
|
||||||
if (arg != null) {
|
final switchUuidIndex = bootArgs.indexOf("--switch_uuid");
|
||||||
if (arg.startsWith(kUniLinksPrefix)) {
|
String? switchUuid = bootArgs.length < switchUuidIndex + 1
|
||||||
return parseRustdeskUri(arg);
|
? null
|
||||||
|
: bootArgs[switchUuidIndex + 1];
|
||||||
|
if (id != null) {
|
||||||
|
if (id.startsWith(kUniLinksPrefix)) {
|
||||||
|
return parseRustdeskUri(id);
|
||||||
} else {
|
} else {
|
||||||
// remove "--connect xxx" in the `bootArgs` array
|
// remove "--connect xxx" in the `bootArgs` array
|
||||||
bootArgs.removeAt(connectIndex);
|
bootArgs.removeAt(connectIndex);
|
||||||
bootArgs.removeAt(connectIndex);
|
bootArgs.removeAt(connectIndex);
|
||||||
// fallback to peer id
|
// fallback to peer id
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
rustDeskWinManager.newRemoteDesktop(arg);
|
rustDeskWinManager.newRemoteDesktop(id, switch_uuid: switchUuid);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1307,8 +1312,10 @@ bool callUniLinksUriHandler(Uri uri) {
|
|||||||
// new connection
|
// new connection
|
||||||
if (uri.authority == "connection" && uri.path.startsWith("/new/")) {
|
if (uri.authority == "connection" && uri.path.startsWith("/new/")) {
|
||||||
final peerId = uri.path.substring("/new/".length);
|
final peerId = uri.path.substring("/new/".length);
|
||||||
|
var param = uri.queryParameters;
|
||||||
|
String? switch_uuid = param["switch_uuid"];
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
rustDeskWinManager.newRemoteDesktop(peerId);
|
rustDeskWinManager.newRemoteDesktop(peerId, switch_uuid: switch_uuid);
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1606,3 +1613,7 @@ Widget dialogButton(String text,
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int version_cmp(String v1, String v2) {
|
||||||
|
return bind.versionToNumber(v: v1) - bind.versionToNumber(v: v2);
|
||||||
|
}
|
||||||
|
|||||||
@ -544,7 +544,7 @@ void setPasswordDialog() async {
|
|||||||
final p1 = TextEditingController(text: pw);
|
final p1 = TextEditingController(text: pw);
|
||||||
var errMsg0 = "";
|
var errMsg0 = "";
|
||||||
var errMsg1 = "";
|
var errMsg1 = "";
|
||||||
final RxString rxPass = p0.text.obs;
|
final RxString rxPass = pw.trim().obs;
|
||||||
final rules = [
|
final rules = [
|
||||||
DigitValidationRule(),
|
DigitValidationRule(),
|
||||||
UppercaseValidationRule(),
|
UppercaseValidationRule(),
|
||||||
@ -603,7 +603,7 @@ void setPasswordDialog() async {
|
|||||||
controller: p0,
|
controller: p0,
|
||||||
focusNode: FocusNode()..requestFocus(),
|
focusNode: FocusNode()..requestFocus(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
rxPass.value = value;
|
rxPass.value = value.trim();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -33,10 +33,12 @@ class RemotePage extends StatefulWidget {
|
|||||||
Key? key,
|
Key? key,
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.menubarState,
|
required this.menubarState,
|
||||||
|
this.switchUuid,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
final MenubarState menubarState;
|
final MenubarState menubarState;
|
||||||
|
final String? switchUuid;
|
||||||
final SimpleWrapper<State<RemotePage>?> _lastState = SimpleWrapper(null);
|
final SimpleWrapper<State<RemotePage>?> _lastState = SimpleWrapper(null);
|
||||||
|
|
||||||
FFI get ffi => (_lastState.value! as _RemotePageState)._ffi;
|
FFI get ffi => (_lastState.value! as _RemotePageState)._ffi;
|
||||||
@ -100,7 +102,10 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
showKBLayoutTypeChooserIfNeeded(
|
showKBLayoutTypeChooserIfNeeded(
|
||||||
_ffi.ffiModel.pi.platform, _ffi.dialogManager);
|
_ffi.ffiModel.pi.platform, _ffi.dialogManager);
|
||||||
});
|
});
|
||||||
_ffi.start(widget.id);
|
_ffi.start(
|
||||||
|
widget.id,
|
||||||
|
switchUuid: widget.switchUuid,
|
||||||
|
);
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
||||||
_ffi.dialogManager
|
_ffi.dialogManager
|
||||||
|
|||||||
@ -64,6 +64,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
key: ValueKey(peerId),
|
key: ValueKey(peerId),
|
||||||
id: peerId,
|
id: peerId,
|
||||||
menubarState: _menubarState,
|
menubarState: _menubarState,
|
||||||
|
switchUuid: params['switch_uuid'],
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
_update_remote_count();
|
_update_remote_count();
|
||||||
@ -84,6 +85,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
if (call.method == "new_remote_desktop") {
|
if (call.method == "new_remote_desktop") {
|
||||||
final args = jsonDecode(call.arguments);
|
final args = jsonDecode(call.arguments);
|
||||||
final id = args['id'];
|
final id = args['id'];
|
||||||
|
final switchUuid = args['switch_uuid'];
|
||||||
window_on_top(windowId());
|
window_on_top(windowId());
|
||||||
ConnectionTypeState.init(id);
|
ConnectionTypeState.init(id);
|
||||||
tabController.add(TabInfo(
|
tabController.add(TabInfo(
|
||||||
@ -96,6 +98,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
key: ValueKey(id),
|
key: ValueKey(id),
|
||||||
id: id,
|
id: id,
|
||||||
menubarState: _menubarState,
|
menubarState: _menubarState,
|
||||||
|
switchUuid: switchUuid,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
} else if (call.method == "onDestroy") {
|
} else if (call.method == "onDestroy") {
|
||||||
|
|||||||
@ -516,6 +516,15 @@ class _CmControlPanel extends StatelessWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
Offstage(
|
||||||
|
offstage: !client.fromSwitch,
|
||||||
|
child: buildButton(context,
|
||||||
|
color: Colors.purple,
|
||||||
|
onClick: () => handleSwitchBack(context),
|
||||||
|
icon: Icon(Icons.reply, color: Colors.white),
|
||||||
|
text: "Switch Sides",
|
||||||
|
textColor: Colors.white),
|
||||||
|
),
|
||||||
Offstage(
|
Offstage(
|
||||||
offstage: !showElevation,
|
offstage: !showElevation,
|
||||||
child: buildButton(context, color: Colors.green[700], onClick: () {
|
child: buildButton(context, color: Colors.green[700], onClick: () {
|
||||||
@ -674,6 +683,10 @@ class _CmControlPanel extends StatelessWidget {
|
|||||||
windowManager.close();
|
windowManager.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleSwitchBack(BuildContext context) {
|
||||||
|
bind.cmSwitchBack(connId: client.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkClickTime(int id, Function() callback) async {
|
void checkClickTime(int id, Function() callback) async {
|
||||||
|
|||||||
@ -509,6 +509,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
List<MenuEntryBase<String>> _getControlMenu(BuildContext context) {
|
List<MenuEntryBase<String>> _getControlMenu(BuildContext context) {
|
||||||
final pi = widget.ffi.ffiModel.pi;
|
final pi = widget.ffi.ffiModel.pi;
|
||||||
final perms = widget.ffi.ffiModel.permissions;
|
final perms = widget.ffi.ffiModel.permissions;
|
||||||
|
final peer_version = widget.ffi.ffiModel.pi.version;
|
||||||
const EdgeInsets padding = EdgeInsets.only(left: 14.0, right: 5.0);
|
const EdgeInsets padding = EdgeInsets.only(left: 14.0, right: 5.0);
|
||||||
final List<MenuEntryBase<String>> displayMenu = [];
|
final List<MenuEntryBase<String>> displayMenu = [];
|
||||||
displayMenu.addAll([
|
displayMenu.addAll([
|
||||||
@ -651,6 +652,19 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
dismissOnClicked: true,
|
dismissOnClicked: true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if (pi.platform != kPeerPlatformAndroid &&
|
||||||
|
version_cmp(peer_version, '1.2.0') >= 0) {
|
||||||
|
displayMenu.add(MenuEntryButton<String>(
|
||||||
|
childBuilder: (TextStyle? style) => Text(
|
||||||
|
translate('Switch Sides'),
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
proc: () =>
|
||||||
|
showConfirmSwitchSidesDialog(widget.id, widget.ffi.dialogManager),
|
||||||
|
padding: padding,
|
||||||
|
dismissOnClicked: true,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pi.version.isNotEmpty) {
|
if (pi.version.isNotEmpty) {
|
||||||
@ -721,6 +735,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
List<MenuEntryBase<String>> _getDisplayMenu(
|
List<MenuEntryBase<String>> _getDisplayMenu(
|
||||||
dynamic futureData, int remoteCount) {
|
dynamic futureData, int remoteCount) {
|
||||||
const EdgeInsets padding = EdgeInsets.only(left: 18.0, right: 8.0);
|
const EdgeInsets padding = EdgeInsets.only(left: 18.0, right: 8.0);
|
||||||
|
final peer_version = widget.ffi.ffiModel.pi.version;
|
||||||
final displayMenu = [
|
final displayMenu = [
|
||||||
MenuEntryRadios<String>(
|
MenuEntryRadios<String>(
|
||||||
text: translate('Ratio'),
|
text: translate('Ratio'),
|
||||||
@ -880,9 +895,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
final fpsSlider = Offstage(
|
final fpsSlider = Offstage(
|
||||||
offstage:
|
offstage:
|
||||||
(await bind.mainIsUsingPublicServer() && direct != true) ||
|
(await bind.mainIsUsingPublicServer() && direct != true) ||
|
||||||
(await bind.versionToNumber(
|
version_cmp(peer_version, '1.2.0') < 0,
|
||||||
v: widget.ffi.ffiModel.pi.version) <
|
|
||||||
await bind.versionToNumber(v: '1.2.0')),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Obx((() => Slider(
|
Obx((() => Slider(
|
||||||
@ -1391,16 +1404,33 @@ void showAuditDialog(String id, dialogManager) async {
|
|||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
)),
|
)),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
dialogButton('Cancel', onPressed: close, isOutline: true),
|
||||||
style: flatButtonStyle,
|
dialogButton('OK', onPressed: submit)
|
||||||
onPressed: close,
|
],
|
||||||
child: Text(translate('Cancel')),
|
onSubmit: submit,
|
||||||
),
|
onCancel: close,
|
||||||
TextButton(
|
);
|
||||||
style: flatButtonStyle,
|
});
|
||||||
onPressed: submit,
|
}
|
||||||
child: Text(translate('OK')),
|
|
||||||
),
|
void showConfirmSwitchSidesDialog(
|
||||||
|
String id, OverlayDialogManager dialogManager) async {
|
||||||
|
dialogManager.show((setState, close) {
|
||||||
|
submit() async {
|
||||||
|
await bind.sessionSwitchSides(id: id);
|
||||||
|
closeConnection(id: id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CustomAlertDialog(
|
||||||
|
title: Text(translate('Switch Sides')),
|
||||||
|
content: Column(
|
||||||
|
children: [
|
||||||
|
Text(translate('Please confirm if you want to share your desktop?')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
dialogButton('Cancel', onPressed: close, isOutline: true),
|
||||||
|
dialogButton('OK', onPressed: submit),
|
||||||
],
|
],
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
onCancel: close,
|
onCancel: close,
|
||||||
|
|||||||
@ -184,13 +184,9 @@ class FfiModel with ChangeNotifier {
|
|||||||
} else if (name == 'update_privacy_mode') {
|
} else if (name == 'update_privacy_mode') {
|
||||||
updatePrivacyMode(evt, peerId);
|
updatePrivacyMode(evt, peerId);
|
||||||
} else if (name == 'new_connection') {
|
} else if (name == 'new_connection') {
|
||||||
var arg = evt['peer_id'].toString();
|
var uni_links = evt['uni_links'].toString();
|
||||||
if (arg.startsWith(kUniLinksPrefix)) {
|
if (uni_links.startsWith(kUniLinksPrefix)) {
|
||||||
parseRustdeskUri(arg);
|
parseRustdeskUri(uni_links);
|
||||||
} else {
|
|
||||||
Future.delayed(Duration.zero, () {
|
|
||||||
rustDeskWinManager.newRemoteDesktop(arg);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if (name == 'alias') {
|
} else if (name == 'alias') {
|
||||||
handleAliasChanged(evt);
|
handleAliasChanged(evt);
|
||||||
@ -199,6 +195,10 @@ class FfiModel with ChangeNotifier {
|
|||||||
parent.target?.serverModel.setShowElevation(show);
|
parent.target?.serverModel.setShowElevation(show);
|
||||||
} else if (name == 'cancel_msgbox') {
|
} else if (name == 'cancel_msgbox') {
|
||||||
cancelMsgBox(evt, peerId);
|
cancelMsgBox(evt, peerId);
|
||||||
|
} else if (name == 'switch_back') {
|
||||||
|
final peer_id = evt['peer_id'].toString();
|
||||||
|
await bind.sessionSwitchSides(id: peer_id);
|
||||||
|
closeConnection(id: peer_id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1289,7 +1289,9 @@ class FFI {
|
|||||||
|
|
||||||
/// Start with the given [id]. Only transfer file if [isFileTransfer], only port forward if [isPortForward].
|
/// Start with the given [id]. Only transfer file if [isFileTransfer], only port forward if [isPortForward].
|
||||||
void start(String id,
|
void start(String id,
|
||||||
{bool isFileTransfer = false, bool isPortForward = false}) {
|
{bool isFileTransfer = false,
|
||||||
|
bool isPortForward = false,
|
||||||
|
String? switchUuid}) {
|
||||||
assert(!(isFileTransfer && isPortForward), 'more than one connect type');
|
assert(!(isFileTransfer && isPortForward), 'more than one connect type');
|
||||||
if (isFileTransfer) {
|
if (isFileTransfer) {
|
||||||
connType = ConnType.fileTransfer;
|
connType = ConnType.fileTransfer;
|
||||||
@ -1305,19 +1307,23 @@ class FFI {
|
|||||||
}
|
}
|
||||||
// ignore: unused_local_variable
|
// ignore: unused_local_variable
|
||||||
final addRes = bind.sessionAddSync(
|
final addRes = bind.sessionAddSync(
|
||||||
id: id, isFileTransfer: isFileTransfer, isPortForward: isPortForward);
|
id: id,
|
||||||
|
isFileTransfer: isFileTransfer,
|
||||||
|
isPortForward: isPortForward,
|
||||||
|
switchUuid: switchUuid ?? "",
|
||||||
|
);
|
||||||
final stream = bind.sessionStart(id: id);
|
final stream = bind.sessionStart(id: id);
|
||||||
final cb = ffiModel.startEventListener(id);
|
final cb = ffiModel.startEventListener(id);
|
||||||
() async {
|
() async {
|
||||||
await for (final message in stream) {
|
await for (final message in stream) {
|
||||||
if (message is Event) {
|
if (message is EventToUI_Event) {
|
||||||
try {
|
try {
|
||||||
Map<String, dynamic> event = json.decode(message.field0);
|
Map<String, dynamic> event = json.decode(message.field0);
|
||||||
await cb(event);
|
await cb(event);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('json.decode fail1(): $e, ${message.field0}');
|
debugPrint('json.decode fail1(): $e, ${message.field0}');
|
||||||
}
|
}
|
||||||
} else if (message is Rgba) {
|
} else if (message is EventToUI_Rgba) {
|
||||||
imageModel.onRgba(message.field0);
|
imageModel.onRgba(message.field0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -601,6 +601,7 @@ class Client {
|
|||||||
bool restart = false;
|
bool restart = false;
|
||||||
bool recording = false;
|
bool recording = false;
|
||||||
bool disconnected = false;
|
bool disconnected = false;
|
||||||
|
bool fromSwitch = false;
|
||||||
|
|
||||||
RxBool hasUnreadChatMessage = false.obs;
|
RxBool hasUnreadChatMessage = false.obs;
|
||||||
|
|
||||||
@ -621,6 +622,7 @@ class Client {
|
|||||||
restart = json['restart'];
|
restart = json['restart'];
|
||||||
recording = json['recording'];
|
recording = json['recording'];
|
||||||
disconnected = json['disconnected'];
|
disconnected = json['disconnected'];
|
||||||
|
fromSwitch = json['from_switch'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
@ -638,6 +640,7 @@ class Client {
|
|||||||
data['restart'] = restart;
|
data['restart'] = restart;
|
||||||
data['recording'] = recording;
|
data['recording'] = recording;
|
||||||
data['disconnected'] = disconnected;
|
data['disconnected'] = disconnected;
|
||||||
|
data['from_switch'] = fromSwitch;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,9 +40,13 @@ class RustDeskMultiWindowManager {
|
|||||||
int? _fileTransferWindowId;
|
int? _fileTransferWindowId;
|
||||||
int? _portForwardWindowId;
|
int? _portForwardWindowId;
|
||||||
|
|
||||||
Future<dynamic> newRemoteDesktop(String remoteId) async {
|
Future<dynamic> newRemoteDesktop(String remoteId,
|
||||||
final msg =
|
{String? switch_uuid}) async {
|
||||||
jsonEncode({"type": WindowType.RemoteDesktop.index, "id": remoteId});
|
final msg = jsonEncode({
|
||||||
|
"type": WindowType.RemoteDesktop.index,
|
||||||
|
"id": remoteId,
|
||||||
|
"switch_uuid": switch_uuid ?? ""
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final ids = await DesktopMultiWindow.getAllSubWindowIds();
|
final ids = await DesktopMultiWindow.getAllSubWindowIds();
|
||||||
|
|||||||
@ -51,11 +51,7 @@ dependencies:
|
|||||||
image_picker: ^0.8.5
|
image_picker: ^0.8.5
|
||||||
image: ^3.1.3
|
image: ^3.1.3
|
||||||
back_button_interceptor: ^6.0.1
|
back_button_interceptor: ^6.0.1
|
||||||
flutter_rust_bridge:
|
flutter_rust_bridge: ^1.61.1
|
||||||
git:
|
|
||||||
url: https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge
|
|
||||||
ref: master
|
|
||||||
path: frb_dart
|
|
||||||
window_manager:
|
window_manager:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Kingtous/rustdesk_window_manager
|
url: https://github.com/Kingtous/rustdesk_window_manager
|
||||||
@ -103,6 +99,7 @@ dev_dependencies:
|
|||||||
build_runner: ^2.1.11
|
build_runner: ^2.1.11
|
||||||
freezed: ^2.0.3
|
freezed: ^2.0.3
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^2.0.0
|
||||||
|
ffigen: ^7.2.4
|
||||||
|
|
||||||
# rerun: flutter pub run flutter_launcher_icons:main
|
# rerun: flutter pub run flutter_launcher_icons:main
|
||||||
icons_launcher:
|
icons_launcher:
|
||||||
|
|||||||
@ -564,6 +564,17 @@ message ElevationRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message SwitchSidesRequest {
|
||||||
|
bytes uuid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SwitchSidesResponse {
|
||||||
|
bytes uuid = 1;
|
||||||
|
LoginRequest lr = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SwitchBack {}
|
||||||
|
|
||||||
message Misc {
|
message Misc {
|
||||||
oneof union {
|
oneof union {
|
||||||
ChatMessage chat_message = 4;
|
ChatMessage chat_message = 4;
|
||||||
@ -582,6 +593,8 @@ message Misc {
|
|||||||
ElevationRequest elevation_request = 18;
|
ElevationRequest elevation_request = 18;
|
||||||
string elevation_response = 19;
|
string elevation_response = 19;
|
||||||
bool portable_service_running = 20;
|
bool portable_service_running = 20;
|
||||||
|
SwitchSidesRequest switch_sides_request = 21;
|
||||||
|
SwitchBack switch_back = 22;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,5 +619,6 @@ message Message {
|
|||||||
Misc misc = 19;
|
Misc misc = 19;
|
||||||
Cliprdr cliprdr = 20;
|
Cliprdr cliprdr = 20;
|
||||||
MessageBox message_box = 21;
|
MessageBox message_box = 21;
|
||||||
|
SwitchSidesResponse switch_sides_response = 22;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
pub use async_trait::async_trait;
|
pub use async_trait::async_trait;
|
||||||
|
use bytes::Bytes;
|
||||||
#[cfg(not(any(target_os = "android", target_os = "linux")))]
|
#[cfg(not(any(target_os = "android", target_os = "linux")))]
|
||||||
use cpal::{
|
use cpal::{
|
||||||
traits::{DeviceTrait, HostTrait, StreamTrait},
|
traits::{DeviceTrait, HostTrait, StreamTrait},
|
||||||
@ -909,6 +910,7 @@ pub struct LoginConfigHandler {
|
|||||||
pub force_relay: bool,
|
pub force_relay: bool,
|
||||||
pub direct: Option<bool>,
|
pub direct: Option<bool>,
|
||||||
pub received: bool,
|
pub received: bool,
|
||||||
|
switch_uuid: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for LoginConfigHandler {
|
impl Deref for LoginConfigHandler {
|
||||||
@ -936,7 +938,7 @@ impl LoginConfigHandler {
|
|||||||
///
|
///
|
||||||
/// * `id` - id of peer
|
/// * `id` - id of peer
|
||||||
/// * `conn_type` - Connection type enum.
|
/// * `conn_type` - Connection type enum.
|
||||||
pub fn initialize(&mut self, id: String, conn_type: ConnType) {
|
pub fn initialize(&mut self, id: String, conn_type: ConnType, switch_uuid: Option<String>) {
|
||||||
self.id = id;
|
self.id = id;
|
||||||
self.conn_type = conn_type;
|
self.conn_type = conn_type;
|
||||||
let config = self.load_config();
|
let config = self.load_config();
|
||||||
@ -948,6 +950,7 @@ impl LoginConfigHandler {
|
|||||||
self.force_relay = !self.get_option("force-always-relay").is_empty();
|
self.force_relay = !self.get_option("force-always-relay").is_empty();
|
||||||
self.direct = None;
|
self.direct = None;
|
||||||
self.received = false;
|
self.received = false;
|
||||||
|
self.switch_uuid = switch_uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the client should auto login.
|
/// Check if the client should auto login.
|
||||||
@ -1784,6 +1787,14 @@ pub async fn handle_hash(
|
|||||||
interface: &impl Interface,
|
interface: &impl Interface,
|
||||||
peer: &mut Stream,
|
peer: &mut Stream,
|
||||||
) {
|
) {
|
||||||
|
lc.write().unwrap().hash = hash.clone();
|
||||||
|
let uuid = lc.read().unwrap().switch_uuid.clone();
|
||||||
|
if let Some(uuid) = uuid {
|
||||||
|
if let Ok(uuid) = uuid::Uuid::from_str(&uuid) {
|
||||||
|
send_switch_login_request(lc.clone(), peer, uuid).await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut password = lc.read().unwrap().password.clone();
|
let mut password = lc.read().unwrap().password.clone();
|
||||||
if password.is_empty() {
|
if password.is_empty() {
|
||||||
if !password_preset.is_empty() {
|
if !password_preset.is_empty() {
|
||||||
@ -1848,6 +1859,26 @@ pub async fn handle_login_from_ui(
|
|||||||
send_login(lc.clone(), hasher2.finalize()[..].into(), peer).await;
|
send_login(lc.clone(), hasher2.finalize()[..].into(), peer).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn send_switch_login_request(
|
||||||
|
lc: Arc<RwLock<LoginConfigHandler>>,
|
||||||
|
peer: &mut Stream,
|
||||||
|
uuid: Uuid,
|
||||||
|
) {
|
||||||
|
let mut msg_out = Message::new();
|
||||||
|
msg_out.set_switch_sides_response(SwitchSidesResponse {
|
||||||
|
uuid: Bytes::from(uuid.as_bytes().to_vec()),
|
||||||
|
lr: hbb_common::protobuf::MessageField::some(
|
||||||
|
lc.read()
|
||||||
|
.unwrap()
|
||||||
|
.create_login_msg(vec![])
|
||||||
|
.login_request()
|
||||||
|
.to_owned(),
|
||||||
|
),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
allow_err!(peer.send(&msg_out).await);
|
||||||
|
}
|
||||||
|
|
||||||
/// Interface for client to send data and commands.
|
/// Interface for client to send data and commands.
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Interface: Send + Clone + 'static + Sized {
|
pub trait Interface: Send + Clone + 'static + Sized {
|
||||||
|
|||||||
@ -1111,6 +1111,10 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(misc::Union::SwitchBack(_)) => {
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
|
self.handler.switch_back(&self.handler.id);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Some(message::Union::TestDelay(t)) => {
|
Some(message::Union::TestDelay(t)) => {
|
||||||
|
|||||||
@ -298,11 +298,27 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<Strin
|
|||||||
eprintln!("please provide a valid peer id");
|
eprintln!("please provide a valid peer id");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
let mut switch_uuid = None;
|
||||||
|
while let Some(item) = args.next() {
|
||||||
|
if item == "--switch_uuid" {
|
||||||
|
switch_uuid = args.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let switch_uuid = switch_uuid.map_or("".to_string(), |p| format!("switch_uuid={}", p));
|
||||||
|
let params = vec![switch_uuid].join("&");
|
||||||
|
let params_flag = if params.is_empty() { "" } else { "?" };
|
||||||
|
#[allow(unused)]
|
||||||
|
let uni_links = format!(
|
||||||
|
"rustdesk://connection/new/{}{}{}",
|
||||||
|
peer_id, params_flag, params
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
use crate::dbus::invoke_new_connection;
|
use crate::dbus::invoke_new_connection;
|
||||||
|
|
||||||
match invoke_new_connection(peer_id) {
|
match invoke_new_connection(uni_links) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -316,7 +332,6 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<Strin
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
use winapi::um::winuser::WM_USER;
|
use winapi::um::winuser::WM_USER;
|
||||||
let uni_links = format!("rustdesk://connection/new/{}", peer_id);
|
|
||||||
let res = crate::platform::send_message_to_hnwd(
|
let res = crate::platform::send_message_to_hnwd(
|
||||||
"FLUTTER_RUNNER_WIN32_WINDOW",
|
"FLUTTER_RUNNER_WIN32_WINDOW",
|
||||||
"RustDesk",
|
"RustDesk",
|
||||||
|
|||||||
@ -1,3 +1,11 @@
|
|||||||
|
use crate::ui_session_interface::{io_loop, InvokeUiSession, Session};
|
||||||
|
use crate::{client::*, flutter_ffi::EventToUI};
|
||||||
|
use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer};
|
||||||
|
use hbb_common::{
|
||||||
|
bail, config::LocalConfig, get_version_number, message_proto::*, rendezvous_proto::ConnType,
|
||||||
|
ResultType,
|
||||||
|
};
|
||||||
|
use serde_json::json;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
ffi::CString,
|
ffi::CString,
|
||||||
@ -5,18 +13,6 @@ use std::{
|
|||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer};
|
|
||||||
|
|
||||||
use hbb_common::{
|
|
||||||
bail, config::LocalConfig, get_version_number, message_proto::*, rendezvous_proto::ConnType,
|
|
||||||
ResultType,
|
|
||||||
};
|
|
||||||
use serde_json::json;
|
|
||||||
|
|
||||||
use crate::ui_session_interface::{io_loop, InvokeUiSession, Session};
|
|
||||||
|
|
||||||
use crate::{client::*, flutter_ffi::EventToUI};
|
|
||||||
|
|
||||||
pub(super) const APP_TYPE_MAIN: &str = "main";
|
pub(super) const APP_TYPE_MAIN: &str = "main";
|
||||||
pub(super) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
|
pub(super) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
|
||||||
pub(super) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
|
pub(super) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
|
||||||
@ -366,7 +362,17 @@ impl InvokeUiSession for FlutterHandler {
|
|||||||
("y", &display.y.to_string()),
|
("y", &display.y.to_string()),
|
||||||
("width", &display.width.to_string()),
|
("width", &display.width.to_string()),
|
||||||
("height", &display.height.to_string()),
|
("height", &display.height.to_string()),
|
||||||
("cursor_embedded", &{if display.cursor_embedded {1} else {0}}.to_string()),
|
(
|
||||||
|
"cursor_embedded",
|
||||||
|
&{
|
||||||
|
if display.cursor_embedded {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -382,6 +388,10 @@ impl InvokeUiSession for FlutterHandler {
|
|||||||
fn clipboard(&self, content: String) {
|
fn clipboard(&self, content: String) {
|
||||||
self.push_event("clipboard", vec![("content", &content)]);
|
self.push_event("clipboard", vec![("content", &content)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn switch_back(&self, peer_id: &str) {
|
||||||
|
self.push_event("switch_back", [("peer_id", peer_id)].into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new remote session with the given id.
|
/// Create a new remote session with the given id.
|
||||||
@ -391,7 +401,12 @@ impl InvokeUiSession for FlutterHandler {
|
|||||||
/// * `id` - The identifier of the remote session with prefix. Regex: [\w]*[\_]*[\d]+
|
/// * `id` - The identifier of the remote session with prefix. Regex: [\w]*[\_]*[\d]+
|
||||||
/// * `is_file_transfer` - If the session is used for file transfer.
|
/// * `is_file_transfer` - If the session is used for file transfer.
|
||||||
/// * `is_port_forward` - If the session is used for port forward.
|
/// * `is_port_forward` - If the session is used for port forward.
|
||||||
pub fn session_add(id: &str, is_file_transfer: bool, is_port_forward: bool) -> ResultType<()> {
|
pub fn session_add(
|
||||||
|
id: &str,
|
||||||
|
is_file_transfer: bool,
|
||||||
|
is_port_forward: bool,
|
||||||
|
switch_uuid: &str,
|
||||||
|
) -> ResultType<()> {
|
||||||
let session_id = get_session_id(id.to_owned());
|
let session_id = get_session_id(id.to_owned());
|
||||||
LocalConfig::set_remote_id(&session_id);
|
LocalConfig::set_remote_id(&session_id);
|
||||||
|
|
||||||
@ -409,11 +424,17 @@ pub fn session_add(id: &str, is_file_transfer: bool, is_port_forward: bool) -> R
|
|||||||
ConnType::DEFAULT_CONN
|
ConnType::DEFAULT_CONN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let switch_uuid = if switch_uuid.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(switch_uuid.to_string())
|
||||||
|
};
|
||||||
|
|
||||||
session
|
session
|
||||||
.lc
|
.lc
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.initialize(session_id, conn_type);
|
.initialize(session_id, conn_type, switch_uuid);
|
||||||
|
|
||||||
if let Some(same_id_session) = SESSIONS.write().unwrap().insert(id.to_owned(), session) {
|
if let Some(same_id_session) = SESSIONS.write().unwrap().insert(id.to_owned(), session) {
|
||||||
same_id_session.close();
|
same_id_session.close();
|
||||||
|
|||||||
@ -84,8 +84,9 @@ pub fn session_add_sync(
|
|||||||
id: String,
|
id: String,
|
||||||
is_file_transfer: bool,
|
is_file_transfer: bool,
|
||||||
is_port_forward: bool,
|
is_port_forward: bool,
|
||||||
|
switch_uuid: String,
|
||||||
) -> SyncReturn<String> {
|
) -> SyncReturn<String> {
|
||||||
if let Err(e) = session_add(&id, is_file_transfer, is_port_forward) {
|
if let Err(e) = session_add(&id, is_file_transfer, is_port_forward, &switch_uuid) {
|
||||||
SyncReturn(format!("Failed to add session with id {}, {}", &id, e))
|
SyncReturn(format!("Failed to add session with id {}, {}", &id, e))
|
||||||
} else {
|
} else {
|
||||||
SyncReturn("".to_owned())
|
SyncReturn("".to_owned())
|
||||||
@ -503,6 +504,12 @@ pub fn session_elevate_with_logon(id: String, username: String, password: String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn session_switch_sides(id: String) {
|
||||||
|
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||||
|
session.switch_sides();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main_get_sound_inputs() -> Vec<String> {
|
pub fn main_get_sound_inputs() -> Vec<String> {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
return get_sound_inputs();
|
return get_sound_inputs();
|
||||||
@ -1065,6 +1072,10 @@ pub fn cm_elevate_portable(conn_id: i32) {
|
|||||||
crate::ui_cm_interface::elevate_portable(conn_id);
|
crate::ui_cm_interface::elevate_portable(conn_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cm_switch_back(conn_id: i32) {
|
||||||
|
crate::ui_cm_interface::switch_back(conn_id);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main_get_icon() -> String {
|
pub fn main_get_icon() -> String {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
||||||
return ui_interface::get_icon();
|
return ui_interface::get_icon();
|
||||||
@ -1107,8 +1118,8 @@ pub fn query_onlines(ids: Vec<String>) {
|
|||||||
crate::rendezvous_mediator::query_online_states(ids, handle_query_onlines)
|
crate::rendezvous_mediator::query_online_states(ids, handle_query_onlines)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn version_to_number(v: String) -> i64 {
|
pub fn version_to_number(v: String) -> SyncReturn<i64> {
|
||||||
hbb_common::get_version_number(&v)
|
SyncReturn(hbb_common::get_version_number(&v))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn option_synced() -> bool {
|
pub fn option_synced() -> bool {
|
||||||
|
|||||||
12
src/ipc.rs
12
src/ipc.rs
@ -166,6 +166,7 @@ pub enum Data {
|
|||||||
file_transfer_enabled: bool,
|
file_transfer_enabled: bool,
|
||||||
restart: bool,
|
restart: bool,
|
||||||
recording: bool,
|
recording: bool,
|
||||||
|
from_switch: bool,
|
||||||
},
|
},
|
||||||
ChatMessage {
|
ChatMessage {
|
||||||
text: String,
|
text: String,
|
||||||
@ -207,6 +208,8 @@ pub enum Data {
|
|||||||
Empty,
|
Empty,
|
||||||
Disconnected,
|
Disconnected,
|
||||||
DataPortableService(DataPortableService),
|
DataPortableService(DataPortableService),
|
||||||
|
SwitchSidesRequest(String),
|
||||||
|
SwitchSidesBack,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
@ -427,6 +430,15 @@ async fn handle(data: Data, stream: &mut Connection) {
|
|||||||
Data::TestRendezvousServer => {
|
Data::TestRendezvousServer => {
|
||||||
crate::test_rendezvous_server();
|
crate::test_rendezvous_server();
|
||||||
}
|
}
|
||||||
|
Data::SwitchSidesRequest(id) => {
|
||||||
|
let uuid = uuid::Uuid::new_v4();
|
||||||
|
crate::server::insert_switch_sides_uuid(id, uuid.clone());
|
||||||
|
allow_err!(
|
||||||
|
stream
|
||||||
|
.send(&Data::SwitchSidesRequest(uuid.to_string()))
|
||||||
|
.await
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", "弱"),
|
("Weak", "弱"),
|
||||||
("Medium", "中"),
|
("Medium", "中"),
|
||||||
("Strong", "强"),
|
("Strong", "强"),
|
||||||
|
("Switch Sides", "反转访问方向"),
|
||||||
|
("Please confirm if you want to share your desktop?", "请确认要让对方访问你的桌面?"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", "Schwach"),
|
("Weak", "Schwach"),
|
||||||
("Medium", "Mittel"),
|
("Medium", "Mittel"),
|
||||||
("Strong", "Stark"),
|
("Strong", "Stark"),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", "Débil"),
|
("Weak", "Débil"),
|
||||||
("Medium", "Media"),
|
("Medium", "Media"),
|
||||||
("Strong", "Fuerte"),
|
("Strong", "Fuerte"),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", "Αδύναμο"),
|
("Weak", "Αδύναμο"),
|
||||||
("Medium", "Μέτριο"),
|
("Medium", "Μέτριο"),
|
||||||
("Strong", "Δυνατό"),
|
("Strong", "Δυνατό"),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", "Debole"),
|
("Weak", "Debole"),
|
||||||
("Medium", "Media"),
|
("Medium", "Media"),
|
||||||
("Strong", "Forte"),
|
("Strong", "Forte"),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", "Слабый"),
|
("Weak", "Слабый"),
|
||||||
("Medium", "Средний"),
|
("Medium", "Средний"),
|
||||||
("Strong", "Стойкий"),
|
("Strong", "Стойкий"),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", "弱"),
|
("Weak", "弱"),
|
||||||
("Medium", "中"),
|
("Medium", "中"),
|
||||||
("Strong", "強"),
|
("Strong", "強"),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -431,5 +431,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Weak", ""),
|
("Weak", ""),
|
||||||
("Medium", ""),
|
("Medium", ""),
|
||||||
("Strong", ""),
|
("Strong", ""),
|
||||||
|
("Switch Sides", ""),
|
||||||
|
("Please confirm if you want to share your desktop?", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -784,12 +784,14 @@ extern "C" fn breakdown_signal_handler(sig: i32) {
|
|||||||
sig,
|
sig,
|
||||||
stack.join("\n").to_string()
|
stack.join("\n").to_string()
|
||||||
);
|
);
|
||||||
system_message(
|
if !info.is_empty() {
|
||||||
"RustDesk",
|
system_message(
|
||||||
&format!("Got signal {} and exit.{}", sig, info),
|
"RustDesk",
|
||||||
true,
|
&format!("Got signal {} and exit.{}", sig, info),
|
||||||
)
|
true,
|
||||||
.ok();
|
)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ lazy_static::lazy_static! {
|
|||||||
static ref LOGIN_FAILURES: Arc::<Mutex<HashMap<String, (i32, i32, i32)>>> = Default::default();
|
static ref LOGIN_FAILURES: Arc::<Mutex<HashMap<String, (i32, i32, i32)>>> = Default::default();
|
||||||
static ref SESSIONS: Arc::<Mutex<HashMap<String, Session>>> = Default::default();
|
static ref SESSIONS: Arc::<Mutex<HashMap<String, Session>>> = Default::default();
|
||||||
static ref ALIVE_CONNS: Arc::<Mutex<Vec<i32>>> = Default::default();
|
static ref ALIVE_CONNS: Arc::<Mutex<Vec<i32>>> = Default::default();
|
||||||
|
static ref SWITCH_SIDES_UUID: Arc::<Mutex<HashMap<String, (Instant, uuid::Uuid)>>> = Default::default();
|
||||||
}
|
}
|
||||||
pub static CLICK_TIME: AtomicI64 = AtomicI64::new(0);
|
pub static CLICK_TIME: AtomicI64 = AtomicI64::new(0);
|
||||||
pub static MOUSE_MOVE_TIME: AtomicI64 = AtomicI64::new(0);
|
pub static MOUSE_MOVE_TIME: AtomicI64 = AtomicI64::new(0);
|
||||||
@ -101,7 +102,9 @@ pub struct Connection {
|
|||||||
last_recv_time: Arc<Mutex<Instant>>,
|
last_recv_time: Arc<Mutex<Instant>>,
|
||||||
chat_unanswered: bool,
|
chat_unanswered: bool,
|
||||||
close_manually: bool,
|
close_manually: bool,
|
||||||
|
#[allow(unused)]
|
||||||
elevation_requested: bool,
|
elevation_requested: bool,
|
||||||
|
from_switch: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subscriber for ConnInner {
|
impl Subscriber for ConnInner {
|
||||||
@ -134,6 +137,7 @@ const MILLI1: Duration = Duration::from_millis(1);
|
|||||||
const SEND_TIMEOUT_VIDEO: u64 = 12_000;
|
const SEND_TIMEOUT_VIDEO: u64 = 12_000;
|
||||||
const SEND_TIMEOUT_OTHER: u64 = SEND_TIMEOUT_VIDEO * 10;
|
const SEND_TIMEOUT_OTHER: u64 = SEND_TIMEOUT_VIDEO * 10;
|
||||||
const SESSION_TIMEOUT: Duration = Duration::from_secs(30);
|
const SESSION_TIMEOUT: Duration = Duration::from_secs(30);
|
||||||
|
const SWITCH_SIDES_TIMEOUT: Duration = Duration::from_secs(10);
|
||||||
|
|
||||||
impl Connection {
|
impl Connection {
|
||||||
pub async fn start(
|
pub async fn start(
|
||||||
@ -198,6 +202,7 @@ impl Connection {
|
|||||||
chat_unanswered: false,
|
chat_unanswered: false,
|
||||||
close_manually: false,
|
close_manually: false,
|
||||||
elevation_requested: false,
|
elevation_requested: false,
|
||||||
|
from_switch: false,
|
||||||
};
|
};
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
@ -362,6 +367,13 @@ impl Connection {
|
|||||||
log::error!("Failed to start portable service from cm:{:?}", e);
|
log::error!("Failed to start portable service from cm:{:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ipc::Data::SwitchSidesBack => {
|
||||||
|
let mut misc = Misc::new();
|
||||||
|
misc.set_switch_back(SwitchBack::default());
|
||||||
|
let mut msg = Message::new();
|
||||||
|
msg.set_misc(misc);
|
||||||
|
conn.send(msg).await;
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -954,6 +966,7 @@ impl Connection {
|
|||||||
file_transfer_enabled: self.file_transfer_enabled(),
|
file_transfer_enabled: self.file_transfer_enabled(),
|
||||||
restart: self.restart,
|
restart: self.restart,
|
||||||
recording: self.recording,
|
recording: self.recording,
|
||||||
|
from_switch: self.from_switch,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1078,29 +1091,33 @@ impl Connection {
|
|||||||
return Config::get_option(enable_prefix_option).is_empty();
|
return Config::get_option(enable_prefix_option).is_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_message(&mut self, msg: Message) -> bool {
|
async fn handle_login_request_without_validation(&mut self, lr: &LoginRequest) {
|
||||||
if let Some(message::Union::LoginRequest(lr)) = msg.union {
|
self.lr = lr.clone();
|
||||||
self.lr = lr.clone();
|
if let Some(o) = lr.option.as_ref() {
|
||||||
if let Some(o) = lr.option.as_ref() {
|
self.update_option(o).await;
|
||||||
self.update_option(o).await;
|
if let Some(q) = o.video_codec_state.clone().take() {
|
||||||
if let Some(q) = o.video_codec_state.clone().take() {
|
scrap::codec::Encoder::update_video_encoder(
|
||||||
scrap::codec::Encoder::update_video_encoder(
|
self.inner.id(),
|
||||||
self.inner.id(),
|
scrap::codec::EncoderUpdate::State(q),
|
||||||
scrap::codec::EncoderUpdate::State(q),
|
);
|
||||||
);
|
|
||||||
} else {
|
|
||||||
scrap::codec::Encoder::update_video_encoder(
|
|
||||||
self.inner.id(),
|
|
||||||
scrap::codec::EncoderUpdate::DisableHwIfNotExist,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
scrap::codec::Encoder::update_video_encoder(
|
scrap::codec::Encoder::update_video_encoder(
|
||||||
self.inner.id(),
|
self.inner.id(),
|
||||||
scrap::codec::EncoderUpdate::DisableHwIfNotExist,
|
scrap::codec::EncoderUpdate::DisableHwIfNotExist,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.video_ack_required = lr.video_ack_required;
|
} else {
|
||||||
|
scrap::codec::Encoder::update_video_encoder(
|
||||||
|
self.inner.id(),
|
||||||
|
scrap::codec::EncoderUpdate::DisableHwIfNotExist,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self.video_ack_required = lr.video_ack_required;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_message(&mut self, msg: Message) -> bool {
|
||||||
|
if let Some(message::Union::LoginRequest(lr)) = msg.union {
|
||||||
|
self.handle_login_request_without_validation(&lr).await;
|
||||||
if self.authorized {
|
if self.authorized {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1247,6 +1264,25 @@ impl Connection {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.update_network_delay(new_delay);
|
.update_network_delay(new_delay);
|
||||||
}
|
}
|
||||||
|
} else if let Some(message::Union::SwitchSidesResponse(_s)) = msg.union {
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
|
if let Some(lr) = _s.lr.clone().take() {
|
||||||
|
self.handle_login_request_without_validation(&lr).await;
|
||||||
|
SWITCH_SIDES_UUID
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.retain(|_, v| v.0.elapsed() < SWITCH_SIDES_TIMEOUT);
|
||||||
|
let uuid_old = SWITCH_SIDES_UUID.lock().unwrap().remove(&lr.my_id);
|
||||||
|
if let Ok(uuid) = uuid::Uuid::from_slice(_s.uuid.to_vec().as_ref()) {
|
||||||
|
if let Some((instant, uuid_old)) = uuid_old {
|
||||||
|
if uuid == uuid_old {
|
||||||
|
self.from_switch = true;
|
||||||
|
self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true);
|
||||||
|
self.send_logon_response().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if self.authorized {
|
} else if self.authorized {
|
||||||
match msg.union {
|
match msg.union {
|
||||||
Some(message::Union::MouseEvent(me)) => {
|
Some(message::Union::MouseEvent(me)) => {
|
||||||
@ -1512,7 +1548,7 @@ impl Connection {
|
|||||||
self.send(msg).await;
|
self.send(msg).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(elevation_request::Union::Logon(r)) => {
|
Some(elevation_request::Union::Logon(_r)) => {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let mut err = "No need to elevate".to_string();
|
let mut err = "No need to elevate".to_string();
|
||||||
@ -1521,7 +1557,8 @@ impl Connection {
|
|||||||
{
|
{
|
||||||
use crate::portable_service::client;
|
use crate::portable_service::client;
|
||||||
err = client::start_portable_service(client::StartPara::Logon(
|
err = client::start_portable_service(client::StartPara::Logon(
|
||||||
r.username, r.password,
|
_r.username,
|
||||||
|
_r.password,
|
||||||
))
|
))
|
||||||
.err()
|
.err()
|
||||||
.map_or("".to_string(), |e| e.to_string());
|
.map_or("".to_string(), |e| e.to_string());
|
||||||
@ -1536,6 +1573,19 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
|
Some(misc::Union::SwitchSidesRequest(s)) => {
|
||||||
|
if let Ok(uuid) = uuid::Uuid::from_slice(&s.uuid.to_vec()[..]) {
|
||||||
|
crate::run_me(vec![
|
||||||
|
"--connect",
|
||||||
|
&self.lr.my_id,
|
||||||
|
"--switch_uuid",
|
||||||
|
uuid.to_string().as_ref(),
|
||||||
|
])
|
||||||
|
.ok();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -1756,6 +1806,13 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_switch_sides_uuid(id: String, uuid: uuid::Uuid) {
|
||||||
|
SWITCH_SIDES_UUID
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(id, (tokio::time::Instant::now(), uuid));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
async fn start_ipc(
|
async fn start_ipc(
|
||||||
mut rx_to_cm: mpsc::UnboundedReceiver<ipc::Data>,
|
mut rx_to_cm: mpsc::UnboundedReceiver<ipc::Data>,
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
/// [Flutter]: handle uni links for linux
|
/// [Flutter]: handle uni links for linux
|
||||||
use dbus::blocking::Connection;
|
use dbus::blocking::Connection;
|
||||||
use dbus_crossroads::{Crossroads, IfaceBuilder};
|
use dbus_crossroads::{Crossroads, IfaceBuilder};
|
||||||
use hbb_common::{log};
|
use hbb_common::log;
|
||||||
use std::{error::Error, fmt, time::Duration};
|
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::{error::Error, fmt, time::Duration};
|
||||||
|
|
||||||
const DBUS_NAME: &str = "org.rustdesk.rustdesk";
|
const DBUS_NAME: &str = "org.rustdesk.rustdesk";
|
||||||
const DBUS_PREFIX: &str = "/dbus";
|
const DBUS_PREFIX: &str = "/dbus";
|
||||||
@ -30,15 +30,16 @@ impl fmt::Display for DbusError {
|
|||||||
impl Error for DbusError {}
|
impl Error for DbusError {}
|
||||||
|
|
||||||
/// invoke new connection from dbus
|
/// invoke new connection from dbus
|
||||||
///
|
///
|
||||||
/// [Tips]:
|
/// [Tips]:
|
||||||
/// How to test by CLI:
|
/// How to test by CLI:
|
||||||
/// - use dbus-send command:
|
/// - use dbus-send command:
|
||||||
/// `dbus-send --session --print-reply --dest=org.rustdesk.rustdesk /dbus org.rustdesk.rustdesk.NewConnection string:'PEER_ID'`
|
/// `dbus-send --session --print-reply --dest=org.rustdesk.rustdesk /dbus org.rustdesk.rustdesk.NewConnection string:'PEER_ID'`
|
||||||
pub fn invoke_new_connection(peer_id: String) -> Result<(), Box<dyn Error>> {
|
pub fn invoke_new_connection(uni_links: String) -> Result<(), Box<dyn Error>> {
|
||||||
let conn = Connection::new_session()?;
|
let conn = Connection::new_session()?;
|
||||||
let proxy = conn.with_proxy(DBUS_NAME, DBUS_PREFIX, DBUS_TIMEOUT);
|
let proxy = conn.with_proxy(DBUS_NAME, DBUS_PREFIX, DBUS_TIMEOUT);
|
||||||
let (ret,): (String,) = proxy.method_call(DBUS_NAME, DBUS_METHOD_NEW_CONNECTION, (peer_id,))?;
|
let (ret,): (String,) =
|
||||||
|
proxy.method_call(DBUS_NAME, DBUS_METHOD_NEW_CONNECTION, (uni_links,))?;
|
||||||
if ret != DBUS_METHOD_RETURN_SUCCESS {
|
if ret != DBUS_METHOD_RETURN_SUCCESS {
|
||||||
log::error!("error on call new connection to dbus server");
|
log::error!("error on call new connection to dbus server");
|
||||||
return Err(Box::new(DbusError("not success".to_string())));
|
return Err(Box::new(DbusError("not success".to_string())));
|
||||||
@ -67,7 +68,7 @@ fn handle_client_message(builder: &mut IfaceBuilder<()>) {
|
|||||||
DBUS_METHOD_NEW_CONNECTION,
|
DBUS_METHOD_NEW_CONNECTION,
|
||||||
(DBUS_METHOD_NEW_CONNECTION_ID,),
|
(DBUS_METHOD_NEW_CONNECTION_ID,),
|
||||||
(DBUS_METHOD_RETURN,),
|
(DBUS_METHOD_RETURN,),
|
||||||
move |_, _, (_peer_id,): (String,)| {
|
move |_, _, (_uni_links,): (String,)| {
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
{
|
{
|
||||||
use crate::flutter::{self, APP_TYPE_MAIN};
|
use crate::flutter::{self, APP_TYPE_MAIN};
|
||||||
@ -79,7 +80,7 @@ fn handle_client_message(builder: &mut IfaceBuilder<()>) {
|
|||||||
{
|
{
|
||||||
let data = HashMap::from([
|
let data = HashMap::from([
|
||||||
("name", "new_connection"),
|
("name", "new_connection"),
|
||||||
("peer_id", _peer_id.as_str())
|
("uni_links", _uni_links.as_str()),
|
||||||
]);
|
]);
|
||||||
if !stream.add(serde_json::ser::to_string(&data).unwrap_or("".to_string())) {
|
if !stream.add(serde_json::ser::to_string(&data).unwrap_or("".to_string())) {
|
||||||
log::error!("failed to add dbus message to flutter global dbus stream.");
|
log::error!("failed to add dbus message to flutter global dbus stream.");
|
||||||
|
|||||||
@ -264,6 +264,8 @@ impl InvokeUiSession for SciterHandler {
|
|||||||
fn update_block_input_state(&self, on: bool) {
|
fn update_block_input_state(&self, on: bool) {
|
||||||
self.call("updateBlockInputState", &make_args!(on));
|
self.call("updateBlockInputState", &make_args!(on));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn switch_back(&self, _id: &str) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SciterSession(Session<SciterHandler>);
|
pub struct SciterSession(Session<SciterHandler>);
|
||||||
@ -440,7 +442,7 @@ impl SciterSession {
|
|||||||
ConnType::DEFAULT_CONN
|
ConnType::DEFAULT_CONN
|
||||||
};
|
};
|
||||||
|
|
||||||
session.lc.write().unwrap().initialize(id, conn_type);
|
session.lc.write().unwrap().initialize(id, conn_type, None);
|
||||||
|
|
||||||
Self(session)
|
Self(session)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ pub struct Client {
|
|||||||
pub file: bool,
|
pub file: bool,
|
||||||
pub restart: bool,
|
pub restart: bool,
|
||||||
pub recording: bool,
|
pub recording: bool,
|
||||||
|
pub from_switch: bool,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
tx: UnboundedSender<Data>,
|
tx: UnboundedSender<Data>,
|
||||||
}
|
}
|
||||||
@ -118,6 +119,7 @@ impl<T: InvokeUiCM> ConnectionManager<T> {
|
|||||||
file: bool,
|
file: bool,
|
||||||
restart: bool,
|
restart: bool,
|
||||||
recording: bool,
|
recording: bool,
|
||||||
|
from_switch: bool,
|
||||||
tx: mpsc::UnboundedSender<Data>,
|
tx: mpsc::UnboundedSender<Data>,
|
||||||
) {
|
) {
|
||||||
let client = Client {
|
let client = Client {
|
||||||
@ -134,6 +136,7 @@ impl<T: InvokeUiCM> ConnectionManager<T> {
|
|||||||
file,
|
file,
|
||||||
restart,
|
restart,
|
||||||
recording,
|
recording,
|
||||||
|
from_switch,
|
||||||
tx,
|
tx,
|
||||||
};
|
};
|
||||||
CLIENTS
|
CLIENTS
|
||||||
@ -241,6 +244,14 @@ pub fn get_clients_length() -> usize {
|
|||||||
clients.len()
|
clients.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
|
pub fn switch_back(id: i32) {
|
||||||
|
if let Some(client) = CLIENTS.read().unwrap().get(&id) {
|
||||||
|
allow_err!(client.tx.send(Data::SwitchSidesBack));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
async fn enable_cliprdr_file_context(&mut self, conn_id: i32, enabled: bool) {
|
async fn enable_cliprdr_file_context(&mut self, conn_id: i32, enabled: bool) {
|
||||||
@ -308,9 +319,9 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
}
|
}
|
||||||
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: _file_transfer_enabled, restart, recording} => {
|
Data::Login{id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, file_transfer_enabled: _file_transfer_enabled, restart, recording, from_switch} => {
|
||||||
log::debug!("conn_id: {}", id);
|
log::debug!("conn_id: {}", id);
|
||||||
self.cm.add_connection(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, restart, recording, self.tx.clone());
|
self.cm.add_connection(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, restart, recording, from_switch,self.tx.clone());
|
||||||
self.authorized = authorized;
|
self.authorized = authorized;
|
||||||
self.conn_id = id;
|
self.conn_id = id;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -498,6 +509,7 @@ pub async fn start_listen<T: InvokeUiCM>(
|
|||||||
file,
|
file,
|
||||||
restart,
|
restart,
|
||||||
recording,
|
recording,
|
||||||
|
from_switch,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
current_id = id;
|
current_id = id;
|
||||||
@ -514,6 +526,7 @@ pub async fn start_listen<T: InvokeUiCM>(
|
|||||||
file,
|
file,
|
||||||
restart,
|
restart,
|
||||||
recording,
|
recording,
|
||||||
|
from_switch,
|
||||||
tx.clone(),
|
tx.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use crate::common::{self, GrabState};
|
|||||||
use crate::keyboard;
|
use crate::keyboard;
|
||||||
use crate::{client::Data, client::Interface};
|
use crate::{client::Data, client::Interface};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use bytes::Bytes;
|
||||||
use hbb_common::config::{Config, LocalConfig, PeerConfig};
|
use hbb_common::config::{Config, LocalConfig, PeerConfig};
|
||||||
use hbb_common::rendezvous_proto::ConnType;
|
use hbb_common::rendezvous_proto::ConnType;
|
||||||
use hbb_common::tokio::{self, sync::mpsc};
|
use hbb_common::tokio::{self, sync::mpsc};
|
||||||
@ -16,8 +17,10 @@ use hbb_common::{fs, get_version_number, log, Stream};
|
|||||||
use rdev::{Event, EventType::*};
|
use rdev::{Event, EventType::*};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
|
use uuid::Uuid;
|
||||||
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
@ -616,6 +619,40 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
pub fn elevate_with_logon(&self, username: String, password: String) {
|
pub fn elevate_with_logon(&self, username: String, password: String) {
|
||||||
self.send(Data::ElevateWithLogon(username, password));
|
self.send(Data::ElevateWithLogon(username, password));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
pub async fn switch_sides(&self) {
|
||||||
|
match crate::ipc::connect(1000, "").await {
|
||||||
|
Ok(mut conn) => {
|
||||||
|
if conn
|
||||||
|
.send(&crate::ipc::Data::SwitchSidesRequest(self.id.to_string()))
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
if let Ok(Some(data)) = conn.next_timeout(1000).await {
|
||||||
|
match data {
|
||||||
|
crate::ipc::Data::SwitchSidesRequest(str_uuid) => {
|
||||||
|
if let Ok(uuid) = Uuid::from_str(&str_uuid) {
|
||||||
|
let mut misc = Misc::new();
|
||||||
|
misc.set_switch_sides_request(SwitchSidesRequest {
|
||||||
|
uuid: Bytes::from(uuid.as_bytes().to_vec()),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
let mut msg_out = Message::new();
|
||||||
|
msg_out.set_misc(misc);
|
||||||
|
self.send(Data::Message(msg_out));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::info!("server not started (will try to start): {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||||
@ -655,6 +692,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
|||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
fn clipboard(&self, content: String);
|
fn clipboard(&self, content: String);
|
||||||
fn cancel_msgbox(&self, tag: &str);
|
fn cancel_msgbox(&self, tag: &str);
|
||||||
|
fn switch_back(&self, id: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: InvokeUiSession> Deref for Session<T> {
|
impl<T: InvokeUiSession> Deref for Session<T> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user