Merge branch 'master' into flutter_desktop

This commit is contained in:
21pages 2022-08-25 11:50:30 +08:00
commit f9db9fc87a
43 changed files with 1282 additions and 85 deletions

352
Cargo.lock generated
View File

@ -23,6 +23,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "ahash"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.18" version = "0.7.18"
@ -127,6 +133,17 @@ dependencies = [
"x11rb", "x11rb",
] ]
[[package]]
name = "async-broadcast"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d26004fe83b2d1cd3a97609b21e39f9a31535822210fe83205d2ce48866ea61"
dependencies = [
"event-listener",
"futures-core",
"parking_lot 0.12.1",
]
[[package]] [[package]]
name = "async-channel" name = "async-channel"
version = "1.6.1" version = "1.6.1"
@ -138,6 +155,20 @@ dependencies = [
"futures-core", "futures-core",
] ]
[[package]]
name = "async-executor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
"once_cell",
"slab",
]
[[package]] [[package]]
name = "async-io" name = "async-io"
version = "1.7.0" version = "1.7.0"
@ -157,6 +188,15 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "async-lock"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6"
dependencies = [
"event-listener",
]
[[package]] [[package]]
name = "async-process" name = "async-process"
version = "1.4.0" version = "1.4.0"
@ -174,6 +214,17 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "async-recursion"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7d78656ba01f1b93024b7c3a0467f1608e4be67d725749fdcd7d2c7678fd7a2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "async-task" name = "async-task"
version = "4.2.0" version = "4.2.0"
@ -976,6 +1027,23 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
[[package]]
name = "dark-light"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b83576e2eee2d9cdaa8d08812ae59cbfe1b5ac7ac5ac4b8400303c6148a88c1"
dependencies = [
"dconf_rs",
"detect-desktop-environment",
"dirs",
"objc",
"rust-ini",
"web-sys",
"winreg 0.8.0",
"zbus",
"zvariant",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.13.4" version = "0.13.4"
@ -1141,6 +1209,12 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "dconf_rs"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b"
[[package]] [[package]]
name = "default-net" name = "default-net"
version = "0.11.0" version = "0.11.0"
@ -1163,6 +1237,23 @@ dependencies = [
"byteorder", "byteorder",
] ]
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "detect-desktop-environment"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810"
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.3" version = "0.10.3"
@ -1183,6 +1274,15 @@ dependencies = [
"dirs-sys-next", "dirs-sys-next",
] ]
[[package]]
name = "dirs"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
dependencies = [
"dirs-sys",
]
[[package]] [[package]]
name = "dirs-next" name = "dirs-next"
version = "2.0.0" version = "2.0.0"
@ -1193,6 +1293,17 @@ dependencies = [
"dirs-sys-next", "dirs-sys-next",
] ]
[[package]]
name = "dirs-sys"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "dirs-sys-next" name = "dirs-sys-next"
version = "0.1.2" version = "0.1.2"
@ -1219,6 +1330,15 @@ dependencies = [
"libloading", "libloading",
] ]
[[package]]
name = "dlv-list"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68df3f2b690c1b86e65ef7830956aededf3cb0a16f898f79b9a6f421a7b6211b"
dependencies = [
"rand 0.8.5",
]
[[package]] [[package]]
name = "docopt" name = "docopt"
version = "1.1.1" version = "1.1.1"
@ -1295,6 +1415,27 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "enumflags2"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb"
dependencies = [
"enumflags2_derive",
"serde 1.0.137",
]
[[package]]
name = "enumflags2_derive"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "env_logger" name = "env_logger"
version = "0.8.4" version = "0.8.4"
@ -1332,6 +1473,27 @@ dependencies = [
"synstructure", "synstructure",
] ]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "error-code" name = "error-code"
version = "2.3.1" version = "2.3.1"
@ -2093,6 +2255,15 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
dependencies = [
"ahash",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.11.2" version = "0.11.2"
@ -2159,6 +2330,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "hound" name = "hound"
version = "3.4.0" version = "3.4.0"
@ -2314,7 +2491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
dependencies = [ dependencies = [
"autocfg 1.1.0", "autocfg 1.1.0",
"hashbrown", "hashbrown 0.11.2",
] ]
[[package]] [[package]]
@ -3124,6 +3301,26 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "ordered-multimap"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c672c7ad9ec066e428c00eb917124a06f08db19e2584de982cc34b1f4c12485"
dependencies = [
"dlv-list",
"hashbrown 0.9.1",
]
[[package]]
name = "ordered-stream"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44630c059eacfd6e08bdaa51b1db2ce33119caa4ddc1235e923109aa5f25ccb1"
dependencies = [
"futures-core",
"pin-project-lite",
]
[[package]] [[package]]
name = "os_str_bytes" name = "os_str_bytes"
version = "6.1.0" version = "6.1.0"
@ -3924,6 +4121,16 @@ dependencies = [
"which 3.1.1", "which 3.1.1",
] ]
[[package]]
name = "rust-ini"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63471c4aa97a1cf8332a5f97709a79a4234698de6a1f5087faf66f2dae810e22"
dependencies = [
"cfg-if 1.0.0",
"ordered-multimap",
]
[[package]] [[package]]
name = "rust-pulsectl" name = "rust-pulsectl"
version = "0.2.12" version = "0.2.12"
@ -3972,10 +4179,12 @@ dependencies = [
"core-graphics 0.22.3", "core-graphics 0.22.3",
"cpal", "cpal",
"ctrlc", "ctrlc",
"dark-light",
"dasp", "dasp",
"default-net", "default-net",
"dispatch", "dispatch",
"enigo", "enigo",
"errno",
"evdev", "evdev",
"flexi_logger", "flexi_logger",
"flutter_rust_bridge", "flutter_rust_bridge",
@ -4293,6 +4502,17 @@ dependencies = [
"serde 1.0.137", "serde 1.0.137",
] ]
[[package]]
name = "serde_repr"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "serde_urlencoded" name = "serde_urlencoded"
version = "0.7.1" version = "0.7.1"
@ -4339,6 +4559,21 @@ dependencies = [
"yaml-rust", "yaml-rust",
] ]
[[package]]
name = "sha1"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
dependencies = [
"sha1_smol",
]
[[package]]
name = "sha1_smol"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.2" version = "0.10.2"
@ -4468,6 +4703,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "stdweb" name = "stdweb"
version = "0.1.3" version = "0.1.3"
@ -4978,6 +5219,16 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "uds_windows"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d"
dependencies = [
"tempfile",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.8" version = "0.3.8"
@ -5592,6 +5843,15 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "winreg"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d107f8c6e916235c4c01cabb3e8acf7bea8ef6a63ca2e7fa0527c049badfc48c"
dependencies = [
"winapi 0.3.9",
]
[[package]] [[package]]
name = "winreg" name = "winreg"
version = "0.10.1" version = "0.10.1"
@ -5695,6 +5955,70 @@ dependencies = [
"linked-hash-map", "linked-hash-map",
] ]
[[package]]
name = "zbus"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d8f1a037b2c4a67d9654dc7bdfa8ff2e80555bbefdd3c1833c1d1b27c963a6b"
dependencies = [
"async-broadcast",
"async-channel",
"async-executor",
"async-io",
"async-lock",
"async-recursion",
"async-task",
"async-trait",
"byteorder",
"derivative",
"dirs",
"enumflags2",
"event-listener",
"futures-core",
"futures-sink",
"futures-util",
"hex",
"lazy_static",
"nix 0.23.1",
"once_cell",
"ordered-stream",
"rand 0.8.5",
"serde 1.0.137",
"serde_repr",
"sha1",
"static_assertions",
"tracing",
"uds_windows",
"winapi 0.3.9",
"zbus_macros",
"zbus_names",
"zvariant",
]
[[package]]
name = "zbus_macros"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f8fb5186d1c87ae88cf234974c240671238b4a679158ad3b94ec465237349a6"
dependencies = [
"proc-macro-crate 1.1.3",
"proc-macro2",
"quote",
"regex",
"syn",
]
[[package]]
name = "zbus_names"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41a408fd8a352695690f53906dc7fd036be924ec51ea5e05666ff42685ed0af5"
dependencies = [
"serde 1.0.137",
"static_assertions",
"zvariant",
]
[[package]] [[package]]
name = "zstd" name = "zstd"
version = "0.9.2+zstd.1.5.1" version = "0.9.2+zstd.1.5.1"
@ -5723,3 +6047,29 @@ dependencies = [
"cc", "cc",
"libc", "libc",
] ]
[[package]]
name = "zvariant"
version = "3.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bd68e4e6432ef19df47d7e90e2e72b5e7e3d778e0ae3baddf12b951265cc758"
dependencies = [
"byteorder",
"enumflags2",
"libc",
"serde 1.0.137",
"static_assertions",
"zvariant_derive",
]
[[package]]
name = "zvariant_derive"
version = "3.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08e977eaa3af652f63d479ce50d924254ad76722a6289ec1a1eac3231ca30430"
dependencies = [
"proc-macro-crate 1.1.3",
"proc-macro2",
"quote",
"syn",
]

View File

@ -60,6 +60,7 @@ bytes = { version = "1.2", features = ["serde"] }
default-net = "0.11.0" default-net = "0.11.0"
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 = { git = "https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge", optional = true }
errno = "0.2.8"
[target.'cfg(not(target_os = "linux"))'.dependencies] [target.'cfg(not(target_os = "linux"))'.dependencies]
reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features=false } reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features=false }
@ -97,6 +98,7 @@ core-foundation = "0.9"
core-graphics = "0.22" core-graphics = "0.22"
include_dir = "0.7.2" include_dir = "0.7.2"
tray-item = "0.7" # looks better than trayicon tray-item = "0.7" # looks better than trayicon
dark-light = "0.2"
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
psimple = { package = "libpulse-simple-binding", version = "2.25" } psimple = { package = "libpulse-simple-binding", version = "2.25" }
@ -140,7 +142,7 @@ identifier = "com.carriez.rustdesk"
icon = ["32x32.png", "128x128.png", "128x128@2x.png"] icon = ["32x32.png", "128x128.png", "128x128@2x.png"]
deb_depends = ["libgtk-3-0", "libxcb-randr0", "libxdo3", "libxfixes3", "libxcb-shape0", "libxcb-xfixes0", "libasound2", "libsystemd0", "pulseaudio", "python3-pip", "curl"] deb_depends = ["libgtk-3-0", "libxcb-randr0", "libxdo3", "libxfixes3", "libxcb-shape0", "libxcb-xfixes0", "libasound2", "libsystemd0", "pulseaudio", "python3-pip", "curl"]
osx_minimum_system_version = "10.14" osx_minimum_system_version = "10.14"
resources = ["mac-tray.png"] resources = ["mac-tray-light.png","mac-tray-dark.png"]
#https://github.com/johnthagen/min-sized-rust #https://github.com/johnthagen/min-sized-rust
[profile.release] [profile.release]

View File

@ -1,7 +1,7 @@
FROM debian FROM debian
WORKDIR / WORKDIR /
RUN apt update -y && apt install -y g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake unzip zip sudo RUN apt update -y && apt install -y g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake unzip zip sudo libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
RUN git clone https://github.com/microsoft/vcpkg && cd vcpkg && git checkout 134505003bb46e20fbace51ccfb69243fbbc5f82 RUN git clone https://github.com/microsoft/vcpkg && cd vcpkg && git checkout 134505003bb46e20fbace51ccfb69243fbbc5f82
RUN /vcpkg/bootstrap-vcpkg.sh -disableMetrics RUN /vcpkg/bootstrap-vcpkg.sh -disableMetrics

View File

@ -29,7 +29,8 @@ Níže jsou uvedeny servery zdarma k vašemu použití (údaje se mohou v čase
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Soul | AWS lightsail | 1 VCPU / 0,5GB RAM | | Soul | AWS lightsail | 1 VCPU / 0,5GB RAM |
| Singapur | Vultr | 1 VCPU / 1GB RAM | | Singapur | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Softwarové součásti, na kterých závisí ## Softwarové součásti, na kterých závisí

View File

@ -28,6 +28,8 @@ Hier sind die Server, die du kostenlos nutzen kannst, es kann sein das sich dies
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | | Singapore | Vultr | 1 VCPU / 1GB RAM | |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM | |
| Germany | Codext | 2 VCPU / 4GB RAM |
| Germany | Hetzner | 4 VCPU / 8GB RAM |
## Abhängigkeiten ## Abhängigkeiten

View File

@ -28,6 +28,8 @@ A continuación se muestran los servidores que está utilizando de forma gratuit
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM | |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Dependencies ## Dependencies

View File

@ -32,6 +32,8 @@
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM | |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## وابستگی ها ## وابستگی ها

View File

@ -27,6 +27,8 @@ Alla on palvelimia, joita voit käyttää ilmaiseksi, ne saattavat muuttua ajan
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM | |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Riippuvuudet ## Riippuvuudet

View File

@ -26,6 +26,8 @@ Ci-dessous se trouvent les serveurs que vous utilisez gratuitement, cela peut ch
- Séoul, AWS lightsail, 1 VCPU/0.5G RAM - Séoul, AWS lightsail, 1 VCPU/0.5G RAM
- Singapour, Vultr, 1 VCPU/1G RAM - Singapour, Vultr, 1 VCPU/1G RAM
- Dallas, Vultr, 1 VCPU/1G RAM - Dallas, Vultr, 1 VCPU/1G RAM
- Germany, Codext, 2 VCPU / 4GB RAM
- Germany, Hetzner, 4 VCPU / 8GB RAM
## Dépendances ## Dépendances

View File

@ -35,6 +35,8 @@ Ezalatt az üzenet alatt találhatóak azok a publikus szerverek, amelyeket ingy
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM | |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Dependencies ## Dependencies

View File

@ -26,7 +26,9 @@ Di bawah ini adalah server yang bisa Anda gunakan secara gratis, dapat berubah s
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Dependencies ## Dependencies

View File

@ -26,7 +26,9 @@ Qui sotto trovate i server che possono essere usati gratuitamente, la lista potr
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Dipendenze ## Dipendenze

View File

@ -31,7 +31,9 @@ RustDeskは誰からの貢献も歓迎します。 貢献するには [`CONTRIBU
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## 依存関係 ## 依存関係

View File

@ -31,7 +31,9 @@ RustDesk는 모든 기여를 환영합니다. 기여하고자 한다면 [`CONTRI
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## 의존관계 ## 의존관계

View File

@ -26,7 +26,9 @@
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## ഡിപെൻഡൻസികൾ ## ഡിപെൻഡൻസികൾ

View File

@ -26,7 +26,9 @@ Onderstaande servers zijn de servers die je gratis kunt gebruiken, ze kunnen op
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Afhankelijkheden ## Afhankelijkheden

View File

@ -26,7 +26,9 @@ Poniżej znajdują się serwery, z których można korzystać za darmo, może si
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapur | Vultr | 1 VCPU / 1GB RAM | | Singapur | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Zależności ## Zależności

View File

@ -28,6 +28,8 @@ Abaixo estão os servidores que você está utilizando de graça, ele pode mudar
| Seul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapura | Vultr | 1 VCPU / 1GB RAM | | Singapura | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Dependências ## Dependências

View File

@ -32,7 +32,9 @@ RustDesk приветствует вклад каждого. Смотрите [`
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Сеул | AWS lightsail | 1 VCPU / 0.5GB RAM | | Сеул | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Сингапур | Vultr | 1 VCPU / 1GB RAM | | Сингапур | Vultr | 1 VCPU / 1GB RAM |
| Даллас | Vultr | 1 VCPU / 1GB RAM | | | Даллас | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Зависимости ## Зависимости

View File

@ -35,7 +35,9 @@ Dưới đây là những máy chủ mà bạn có thể sử dụng mà không
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Dallas | Vultr | 1 VCPU / 1GB RAM |
| Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Dependencies ## Dependencies

View File

@ -27,6 +27,8 @@ Chat with us: [知乎](https://www.zhihu.com/people/rustdesk) | [Discord](https:
- 首尔, AWS lightsail, 1 VCPU/0.5G RAM - 首尔, AWS lightsail, 1 VCPU/0.5G RAM
- 新加坡, Vultr, 1 VCPU/1G RAM - 新加坡, Vultr, 1 VCPU/1G RAM
- 达拉斯, Vultr, 1 VCPU/1G RAM - 达拉斯, Vultr, 1 VCPU/1G RAM
- Germany, Codext, 2 VCPU / 4GB RAM
- Germany, Hetzner, 4 VCPU / 8GB RAM
## 依赖 ## 依赖

View File

@ -34,7 +34,8 @@ Below are the servers you are using for free, it may change along the time. If y
| --------- | ------------- | ------------------ | | --------- | ------------- | ------------------ |
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM | | Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
| Singapore | Vultr | 1 VCPU / 1GB RAM | | Singapore | Vultr | 1 VCPU / 1GB RAM |
| Dallas | Vultr | 1 VCPU / 1GB RAM | | | Germany | Hetzner | 2 VCPU / 4GB RAM |
| Germany | Codext | 4 VCPU / 8GB RAM |
## Dependencies ## Dependencies

View File

@ -40,12 +40,12 @@ AppDir:
- sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates universe - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates universe
- sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic multiverse - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic multiverse
- sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates multiverse - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates multiverse
- sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-backports main restricted - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-backports main restricted universe multiverse
universe multiverse
- sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security main restricted - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security main restricted
- sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security universe - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security universe
- sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security multiverse - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security multiverse
include: include:
- libc6:amd64
- libgcc1:amd64 - libgcc1:amd64
- libgcrypt20:amd64 - libgcrypt20:amd64
- libgtk-3-0:amd64 - libgtk-3-0:amd64
@ -95,4 +95,4 @@ AppDir:
command: ./AppRun command: ./AppRun
AppImage: AppImage:
arch: x86_64 arch: x86_64
update-information: guess update-information: guess

View File

@ -119,7 +119,7 @@ packages:
name: built_value name: built_value
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "8.4.0" version: "8.4.1"
cached_network_image: cached_network_image:
dependency: transitive dependency: transitive
description: description:
@ -340,35 +340,35 @@ packages:
name: file name: file
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "6.1.2" version: "6.1.4"
firebase_analytics: firebase_analytics:
dependency: "direct main" dependency: "direct main"
description: description:
name: firebase_analytics name: firebase_analytics
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "9.3.1" version: "9.3.2"
firebase_analytics_platform_interface: firebase_analytics_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_analytics_platform_interface name: firebase_analytics_platform_interface
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.3.1" version: "3.3.2"
firebase_analytics_web: firebase_analytics_web:
dependency: transitive dependency: transitive
description: description:
name: firebase_analytics_web name: firebase_analytics_web
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.4.2+1" version: "0.4.2+2"
firebase_core: firebase_core:
dependency: transitive dependency: transitive
description: description:
name: firebase_core name: firebase_core
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.20.1" version: "1.21.0"
firebase_core_platform_interface: firebase_core_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -819,7 +819,7 @@ packages:
name: pubspec_parse name: pubspec_parse
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
qr_code_scanner: qr_code_scanner:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1134,14 +1134,14 @@ packages:
name: video_player name: video_player
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.4.6" version: "2.4.7"
video_player_android: video_player_android:
dependency: transitive dependency: transitive
description: description:
name: video_player_android name: video_player_android
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.3.8" version: "2.3.9"
video_player_avfoundation: video_player_avfoundation:
dependency: transitive dependency: transitive
description: description:
@ -1234,7 +1234,7 @@ packages:
resolved-ref: "799ef079e87938c3f4340591b4330c2598f38bb9" resolved-ref: "799ef079e87938c3f4340591b4330c2598f38bb9"
url: "https://github.com/Kingtous/rustdesk_window_manager" url: "https://github.com/Kingtous/rustdesk_window_manager"
source: git source: git
version: "0.2.5" version: "0.2.6"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View File

@ -23,6 +23,7 @@ use crate::{
pub const RENDEZVOUS_TIMEOUT: u64 = 12_000; pub const RENDEZVOUS_TIMEOUT: u64 = 12_000;
pub const CONNECT_TIMEOUT: u64 = 18_000; pub const CONNECT_TIMEOUT: u64 = 18_000;
pub const READ_TIMEOUT: u64 = 30_000;
pub const REG_INTERVAL: i64 = 12_000; pub const REG_INTERVAL: i64 = 12_000;
pub const COMPRESS_LEVEL: i32 = 3; pub const COMPRESS_LEVEL: i32 = 3;
const SERIAL: i32 = 3; const SERIAL: i32 = 3;
@ -294,8 +295,37 @@ impl Config {
fn load() -> Config { fn load() -> Config {
let mut config = Config::load_::<Config>(""); let mut config = Config::load_::<Config>("");
let (password, _, store) = decrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION); let mut store = false;
let (password, _, store1) = decrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION);
config.password = password; config.password = password;
store |= store1;
let mut id_valid = false;
let (id, encrypted, store2) = decrypt_str_or_original(&config.id, PASSWORD_ENC_VERSION);
if encrypted {
config.id = id;
id_valid = true;
store |= store2;
} else {
if crate::get_modified_time(&Self::file_(""))
.checked_sub(std::time::Duration::from_secs(30)) // allow modification during installation
.unwrap_or(crate::get_exe_time())
< crate::get_exe_time()
{
id_valid = true;
store = true;
}
}
if !id_valid {
for _ in 0..3 {
if let Some(id) = Config::get_auto_id() {
config.id = id;
store = true;
break;
} else {
log::error!("Failed to generate new id");
}
}
}
if store { if store {
config.store(); config.store();
} }
@ -305,6 +335,7 @@ impl Config {
fn store(&self) { fn store(&self) {
let mut config = self.clone(); let mut config = self.clone();
config.password = encrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION); config.password = encrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION);
config.id = encrypt_str_or_original(&config.id, PASSWORD_ENC_VERSION);
Config::store_(&config, ""); Config::store_(&config, "");
} }

View File

@ -202,6 +202,24 @@ pub fn get_modified_time(path: &std::path::Path) -> SystemTime {
.unwrap_or(UNIX_EPOCH) .unwrap_or(UNIX_EPOCH)
} }
pub fn get_created_time(path: &std::path::Path) -> SystemTime {
std::fs::metadata(&path)
.map(|m| m.created().unwrap_or(UNIX_EPOCH))
.unwrap_or(UNIX_EPOCH)
}
pub fn get_exe_time() -> SystemTime {
std::env::current_exe().map_or(UNIX_EPOCH, |path| {
let m = get_modified_time(&path);
let c = get_created_time(&path);
if m > c {
m
} else {
c
}
})
}
pub fn get_uuid() -> Vec<u8> { pub fn get_uuid() -> Vec<u8> {
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
if let Ok(id) = machine_uid::get() { if let Ok(id) = machine_uid::get() {

View File

@ -108,7 +108,7 @@ pub fn encrypt_vec_or_original(v: &[u8], version: &str) -> Vec<u8> {
v.to_owned() v.to_owned()
} }
// String: password // Vec<u8>: password
// bool: whether decryption is successful // bool: whether decryption is successful
// bool: whether should store to re-encrypt when load // bool: whether should store to re-encrypt when load
pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec<u8>, bool, bool) { pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec<u8>, bool, bool) {

View File

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 391 B

BIN
mac-tray-light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

View File

@ -8,7 +8,7 @@ Icon=/usr/share/rustdesk/files/rustdesk.png
Terminal=false Terminal=false
Type=Application Type=Application
StartupNotify=true StartupNotify=true
Categories=Other; Categories=Network;RemoteAccess;GTK;
Keywords=internet; Keywords=internet;
Actions=new-window; Actions=new-window;

View File

@ -20,7 +20,10 @@ use hbb_common::{
allow_err, allow_err,
anyhow::{anyhow, Context}, anyhow::{anyhow, Context},
bail, bail,
config::{Config, PeerConfig, PeerInfoSerde, CONNECT_TIMEOUT, RELAY_PORT, RENDEZVOUS_TIMEOUT}, config::{
Config, PeerConfig, PeerInfoSerde, CONNECT_TIMEOUT, READ_TIMEOUT, RELAY_PORT,
RENDEZVOUS_TIMEOUT,
},
log, log,
message_proto::{option_message::BoolOption, *}, message_proto::{option_message::BoolOption, *},
protobuf::Message as _, protobuf::Message as _,
@ -121,8 +124,9 @@ impl Client {
key: &str, key: &str,
token: &str, token: &str,
conn_type: ConnType, conn_type: ConnType,
interface: impl Interface,
) -> ResultType<(Stream, bool)> { ) -> ResultType<(Stream, bool)> {
match Self::_start(peer, key, token, conn_type).await { match Self::_start(peer, key, token, conn_type, interface).await {
Err(err) => { Err(err) => {
let err_str = err.to_string(); let err_str = err.to_string();
if err_str.starts_with("Failed") { if err_str.starts_with("Failed") {
@ -141,6 +145,7 @@ impl Client {
key: &str, key: &str,
token: &str, token: &str,
conn_type: ConnType, conn_type: ConnType,
interface: impl Interface,
) -> ResultType<(Stream, bool)> { ) -> ResultType<(Stream, bool)> {
// to-do: remember the port for each peer, so that we can retry easier // to-do: remember the port for each peer, so that we can retry easier
let any_addr = Config::get_any_listen_addr(); let any_addr = Config::get_any_listen_addr();
@ -187,7 +192,11 @@ impl Client {
log::info!("#{} punch attempt with {}, id: {}", i, my_addr, peer); log::info!("#{} punch attempt with {}, id: {}", i, my_addr, peer);
let mut msg_out = RendezvousMessage::new(); let mut msg_out = RendezvousMessage::new();
use hbb_common::protobuf::Enum; use hbb_common::protobuf::Enum;
let nat_type = NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT); let nat_type = if interface.is_force_relay() {
NatType::SYMMETRIC
} else {
NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT)
};
msg_out.set_punch_hole_request(PunchHoleRequest { msg_out.set_punch_hole_request(PunchHoleRequest {
id: peer.to_owned(), id: peer.to_owned(),
token: token.to_owned(), token: token.to_owned(),
@ -239,7 +248,15 @@ impl Client {
let mut conn = let mut conn =
Self::create_relay(peer, rr.uuid, rr.relay_server, key, conn_type) Self::create_relay(peer, rr.uuid, rr.relay_server, key, conn_type)
.await?; .await?;
Self::secure_connection(peer, signed_id_pk, key, &mut conn).await?; Self::secure_connection(
peer,
signed_id_pk,
key,
&mut conn,
false,
interface,
)
.await?;
return Ok((conn, false)); return Ok((conn, false));
} }
_ => { _ => {
@ -280,6 +297,7 @@ impl Client {
key, key,
token, token,
conn_type, conn_type,
interface,
) )
.await .await
} }
@ -299,6 +317,7 @@ impl Client {
key: &str, key: &str,
token: &str, token: &str,
conn_type: ConnType, conn_type: ConnType,
interface: impl Interface,
) -> ResultType<(Stream, bool)> { ) -> ResultType<(Stream, bool)> {
let direct_failures = PeerConfig::load(peer_id).direct_failures; let direct_failures = PeerConfig::load(peer_id).direct_failures;
let mut connect_timeout = 0; let mut connect_timeout = 0;
@ -336,8 +355,8 @@ impl Client {
let start = std::time::Instant::now(); let start = std::time::Instant::now();
// NOTICE: Socks5 is be used event in intranet. Which may be not a good way. // NOTICE: Socks5 is be used event in intranet. Which may be not a good way.
let mut conn = socket_client::connect_tcp(peer, local_addr, connect_timeout).await; let mut conn = socket_client::connect_tcp(peer, local_addr, connect_timeout).await;
let direct = !conn.is_err(); let mut direct = !conn.is_err();
if conn.is_err() { if interface.is_force_relay() || conn.is_err() {
if !relay_server.is_empty() { if !relay_server.is_empty() {
conn = Self::request_relay( conn = Self::request_relay(
peer_id, peer_id,
@ -355,6 +374,7 @@ impl Client {
conn.err().unwrap() conn.err().unwrap()
); );
} }
direct = false;
} else { } else {
bail!("Failed to make direct connection to remote desktop"); bail!("Failed to make direct connection to remote desktop");
} }
@ -367,7 +387,7 @@ impl Client {
} }
let mut conn = conn?; let mut conn = conn?;
log::info!("{:?} used to establish connection", start.elapsed()); log::info!("{:?} used to establish connection", start.elapsed());
Self::secure_connection(peer_id, signed_id_pk, key, &mut conn).await?; Self::secure_connection(peer_id, signed_id_pk, key, &mut conn, direct, interface).await?;
Ok((conn, direct)) Ok((conn, direct))
} }
@ -377,6 +397,8 @@ impl Client {
signed_id_pk: Vec<u8>, signed_id_pk: Vec<u8>,
key: &str, key: &str,
conn: &mut Stream, conn: &mut Stream,
direct: bool,
mut interface: impl Interface,
) -> ResultType<()> { ) -> ResultType<()> {
let rs_pk = get_rs_pk(if key.is_empty() { let rs_pk = get_rs_pk(if key.is_empty() {
hbb_common::config::RS_PUB_KEY hbb_common::config::RS_PUB_KEY
@ -402,9 +424,15 @@ impl Client {
return Ok(()); return Ok(());
} }
}; };
match timeout(CONNECT_TIMEOUT, conn.next()).await? { match timeout(READ_TIMEOUT, conn.next()).await? {
Some(res) => { Some(res) => {
let bytes = res?; let bytes = match res {
Ok(bytes) => bytes,
Err(err) => {
interface.set_force_relay(direct, false);
bail!("{}", err);
}
};
if let Ok(msg_in) = Message::parse_from_bytes(&bytes) { if let Ok(msg_in) = Message::parse_from_bytes(&bytes) {
if let Some(message::Union::SignedId(si)) = msg_in.union { if let Some(message::Union::SignedId(si)) = msg_in.union {
if let Ok((id, their_pk_b)) = decode_id_pk(&si.id, &sign_pk) { if let Ok((id, their_pk_b)) = decode_id_pk(&si.id, &sign_pk) {
@ -831,6 +859,7 @@ pub struct LoginConfigHandler {
session_id: u64, session_id: u64,
pub supported_encoding: Option<(bool, bool)>, pub supported_encoding: Option<(bool, bool)>,
pub restarting_remote_device: bool, pub restarting_remote_device: bool,
pub force_relay: bool,
} }
impl Deref for LoginConfigHandler { impl Deref for LoginConfigHandler {
@ -869,6 +898,7 @@ impl LoginConfigHandler {
self.session_id = rand::random(); self.session_id = rand::random();
self.supported_encoding = None; self.supported_encoding = None;
self.restarting_remote_device = false; self.restarting_remote_device = false;
self.force_relay = !self.get_option("force-always-relay").is_empty();
} }
/// Check if the client should auto login. /// Check if the client should auto login.
@ -1620,6 +1650,8 @@ pub trait Interface: Send + Clone + 'static + Sized {
fn msgbox(&self, msgtype: &str, title: &str, text: &str); fn msgbox(&self, msgtype: &str, title: &str, text: &str);
fn handle_login_error(&mut self, err: &str) -> bool; fn handle_login_error(&mut self, err: &str) -> bool;
fn handle_peer_info(&mut self, pi: PeerInfo); fn handle_peer_info(&mut self, pi: PeerInfo);
fn set_force_relay(&mut self, direct: bool, received: bool);
fn is_force_relay(&self) -> bool;
async fn handle_hash(&mut self, pass: &str, hash: Hash, peer: &mut Stream); async fn handle_hash(&mut self, pass: &str, hash: Hash, peer: &mut Stream);
async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream); async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream);
async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream); async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream);
@ -1790,14 +1822,16 @@ lazy_static::lazy_static! {
pub fn check_if_retry(msgtype: &str, title: &str, text: &str) -> bool { pub fn check_if_retry(msgtype: &str, title: &str, text: &str) -> bool {
msgtype == "error" msgtype == "error"
&& title == "Connection Error" && title == "Connection Error"
&& !text.to_lowercase().contains("offline") && (text.contains("10054")
&& !text.to_lowercase().contains("exist") || text.contains("104")
&& !text.to_lowercase().contains("handshake") || (!text.to_lowercase().contains("offline")
&& !text.to_lowercase().contains("failed") && !text.to_lowercase().contains("exist")
&& !text.to_lowercase().contains("resolve") && !text.to_lowercase().contains("handshake")
&& !text.to_lowercase().contains("mismatch") && !text.to_lowercase().contains("failed")
&& !text.to_lowercase().contains("manually") && !text.to_lowercase().contains("resolve")
&& !text.to_lowercase().contains("not allowed") && !text.to_lowercase().contains("mismatch")
&& !text.to_lowercase().contains("manually")
&& !text.to_lowercase().contains("not allowed")))
} }
#[inline] #[inline]

View File

@ -618,6 +618,24 @@ impl Interface for Session {
} }
} }
fn set_force_relay(&mut self, direct: bool, received: bool) {
let mut lc = self.lc.write().unwrap();
lc.force_relay = false;
if direct && !received {
let errno = errno::errno().0;
log::info!("errno is {}", errno);
// TODO: check mac and ios
if cfg!(windows) && errno == 10054 || !cfg!(windows) && errno == 104 {
lc.force_relay = true;
lc.set_option("force-always-relay".to_owned(), "Y".to_owned());
}
}
}
fn is_force_relay(&self) -> bool {
self.lc.read().unwrap().force_relay
}
async fn handle_hash(&mut self, pass: &str, hash: Hash, peer: &mut Stream) { async fn handle_hash(&mut self, pass: &str, hash: Hash, peer: &mut Stream) {
handle_hash(self.lc.clone(), pass, hash, self, peer).await; handle_hash(self.lc.clone(), pass, hash, self, peer).await;
} }
@ -735,7 +753,7 @@ impl Connection {
let key = Config::get_option("key"); let key = Config::get_option("key");
let token = Config::get_option("access_token"); let token = Config::get_option("access_token");
match Client::start(&session.id, &key, &token, conn_type).await { match Client::start(&session.id, &key, &token, conn_type, session.clone()).await {
Ok((mut peer, direct)) => { Ok((mut peer, direct)) => {
SERVER_KEYBOARD_ENABLED.store(true, Ordering::SeqCst); SERVER_KEYBOARD_ENABLED.store(true, Ordering::SeqCst);
SERVER_CLIPBOARD_ENABLED.store(true, Ordering::SeqCst); SERVER_CLIPBOARD_ENABLED.store(true, Ordering::SeqCst);

View File

@ -13,6 +13,7 @@ mod hu;
mod id; mod id;
mod it; mod it;
mod ja; mod ja;
mod ko;
mod pl; mod pl;
mod ptbr; mod ptbr;
mod ru; mod ru;
@ -43,6 +44,7 @@ lazy_static::lazy_static! {
("vn", "Tiếng Việt"), ("vn", "Tiếng Việt"),
("pl", "Polski"), ("pl", "Polski"),
("ja", "日本語"), ("ja", "日本語"),
("ko", "한국어"),
]); ]);
} }
@ -90,6 +92,7 @@ pub fn translate_locale(name: String, locale: &str) -> String {
"vn" => vn::T.deref(), "vn" => vn::T.deref(),
"pl" => pl::T.deref(), "pl" => pl::T.deref(),
"ja" => ja::T.deref(), "ja" => ja::T.deref(),
"ko" => ko::T.deref(),
_ => en::T.deref(), _ => en::T.deref(),
}; };
if let Some(v) = m.get(&name as &str) { if let Some(v) = m.get(&name as &str) {

View File

@ -35,9 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("About", "Informazioni"), ("About", "Informazioni"),
("Mute", "Silenzia"), ("Mute", "Silenzia"),
("Audio Input", "Input audio"), ("Audio Input", "Input audio"),
("Enhancements", ""), ("Enhancements", "Miglioramenti"),
("Hardware Codec", ""), ("Hardware Codec", "Codifica Hardware"),
("Adaptive Bitrate", ""), ("Adaptive Bitrate", "Bitrate Adattivo"),
("ID Server", "ID server"), ("ID Server", "ID server"),
("Relay Server", "Server relay"), ("Relay Server", "Server relay"),
("API Server", "Server API"), ("API Server", "Server API"),
@ -53,10 +53,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Close", "Chiudi"), ("Close", "Chiudi"),
("Retry", "Riprova"), ("Retry", "Riprova"),
("OK", "OK"), ("OK", "OK"),
("Password Required", "Password richiesta"), ("Password Required", "Password Richiesta"),
("Please enter your password", "Inserisci la tua password"), ("Please enter your password", "Inserisci la tua password"),
("Remember password", "Ricorda password"), ("Remember password", "Ricorda password"),
("Wrong Password", "Password errata"), ("Wrong Password", "Password Errata"),
("Do you want to enter again?", "Vuoi riprovare?"), ("Do you want to enter again?", "Vuoi riprovare?"),
("Connection Error", "Errore di connessione"), ("Connection Error", "Errore di connessione"),
("Error", "Errore"), ("Error", "Errore"),
@ -64,7 +64,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Connecting...", "Connessione..."), ("Connecting...", "Connessione..."),
("Connection in progress. Please wait.", "Connessione in corso. Attendi."), ("Connection in progress. Please wait.", "Connessione in corso. Attendi."),
("Please try 1 minute later", "Per favore riprova fra 1 minuto"), ("Please try 1 minute later", "Per favore riprova fra 1 minuto"),
("Login Error", "Errore di login"), ("Login Error", "Errore Login"),
("Successful", "Successo"), ("Successful", "Successo"),
("Connected, waiting for image...", "Connesso, in attesa dell'immagine..."), ("Connected, waiting for image...", "Connesso, in attesa dell'immagine..."),
("Name", "Nome"), ("Name", "Nome"),
@ -222,7 +222,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Discovered", "Rilevati"), ("Discovered", "Rilevati"),
("install_daemon_tip", "Per avviarsi all'accensione, è necessario installare il servizio di sistema."), ("install_daemon_tip", "Per avviarsi all'accensione, è necessario installare il servizio di sistema."),
("Remote ID", "ID remoto"), ("Remote ID", "ID remoto"),
("Paste", "Impasto"), ("Paste", "Incolla"),
("Paste here?", "Incolla qui?"), ("Paste here?", "Incolla qui?"),
("Are you sure to close the connection?", "Sei sicuro di voler chiudere la connessione?"), ("Are you sure to close the connection?", "Sei sicuro di voler chiudere la connessione?"),
("Download new version", "Scarica nuova versione"), ("Download new version", "Scarica nuova versione"),
@ -241,8 +241,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Two-Finger Move", "Movimento con due dita"), ("Two-Finger Move", "Movimento con due dita"),
("Canvas Move", "Sposta tela"), ("Canvas Move", "Sposta tela"),
("Pinch to Zoom", "Pizzica per zoomare"), ("Pinch to Zoom", "Pizzica per zoomare"),
("Canvas Zoom", "Zoom tela"), ("Canvas Zoom", "Zoom canvas"),
("Reset canvas", "Ripristina tela"), ("Reset canvas", "Ripristina canvas"),
("No permission of file transfer", "Nessun permesso di trasferimento di file"), ("No permission of file transfer", "Nessun permesso di trasferimento di file"),
("Note", "Nota"), ("Note", "Nota"),
("Connection", "Connessione"), ("Connection", "Connessione"),
@ -278,7 +278,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Succeeded", "Successo"), ("Succeeded", "Successo"),
("Someone turns on privacy mode, exit", "Qualcuno attiva la modalità privacy, esci"), ("Someone turns on privacy mode, exit", "Qualcuno attiva la modalità privacy, esci"),
("Unsupported", "Non supportato"), ("Unsupported", "Non supportato"),
("Peer denied", "Pari negato"), ("Peer denied", "Peer negato"),
("Please install plugins", "Si prega di installare i plugin"), ("Please install plugins", "Si prega di installare i plugin"),
("Peer exit", "Uscita tra pari"), ("Peer exit", "Uscita tra pari"),
("Failed to turn off", "Impossibile spegnere"), ("Failed to turn off", "Impossibile spegnere"),
@ -289,18 +289,17 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""), ("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""), ("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""), ("android_open_battery_optimizations_tip", ""),
("Connection not allowed", ""), ("Connection not allowed", "Connessione non consentita"),
("Use temporary password", ""), ("Use temporary password", "Usa password temporanea"),
("Use permanent password", ""), ("Use permanent password", "Usa password permanente"),
("Use both passwords", ""), ("Use both passwords", "Usa entrambe le password"),
("Set permanent password", ""), ("Set permanent password", "Imposta password permanente"),
("Set temporary password length", ""), ("Set temporary password length", "Imposta lunghezza passwod temporanea"),
("Enable Remote Restart", ""), ("Enable Remote Restart", "Abilita riavvio da remoto"),
("Allow remote restart", ""), ("Allow remote restart", "Consenti riavvio da remoto"),
("Restart Remote Device", ""), ("Restart Remote Device", "Riavvia dispositivo remoto"),
("Are you sure you want to restart", ""), ("Are you sure you want to restart", "Sei sicuro di voler riavviare?"),
("Restarting Remote Device", ""), ("Restarting Remote Device", "Il dispositivo remoto si sta riavviando"),
("remote_restarting_tip", ""), ("remote_restarting_tip", "Riavviare il dispositivo remoto"),
("Copied", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -103,8 +103,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Original", "オリジナル"), ("Original", "オリジナル"),
("Shrink", "縮小"), ("Shrink", "縮小"),
("Stretch", "伸縮"), ("Stretch", "伸縮"),
("Scrollbar", "スクロール・バー"),
("ScrollAuto", "自動スクロール"),
("Good image quality", "画質優先"), ("Good image quality", "画質優先"),
("Balanced", "バランス"), ("Balanced", "バランス"),
("Optimize reaction time", "速度優先"), ("Optimize reaction time", "速度優先"),

303
src/lang/ko.rs Normal file
View File

@ -0,0 +1,303 @@
lazy_static::lazy_static! {
pub static ref T: std::collections::HashMap<&'static str, &'static str> =
[
("Status", "상태"),
("Your Desktop", "당신의 데스크탑"),
("desk_tip", "아래 ID와 비밀번호를 통해 당신의 데스크탑으로 접속할 수 있습니다."),
("Password", "비밀번호"),
("Ready", "준비"),
("Established", "연결됨"),
("connecting_status", "RustDesk 네트워크로 연결중입니다..."),
("Enable Service", "서비스 활성화"),
("Start Service", "서비스 시작"),
("Service is running", "서비스 동작중"),
("Service is not running", "서비스가 동작하고 있지 않습니다"),
("not_ready_status", "준비되지 않음. 연결을 확인해주시길 바랍니다."),
("Control Remote Desktop", "원격 데스크탑 제어"),
("Transfer File", "파일 전송"),
("Connect", "접속하기"),
("Recent Sessions", "최근 세션"),
("Address Book", "세션 주소록"),
("Confirmation", "확인"),
("TCP Tunneling", "TCP 터널링"),
("Remove", "삭제"),
("Refresh random password", "랜덤 비밀번호 새로고침"),
("Set your own password", "개인 비밀번호 설정"),
("Enable Keyboard/Mouse", "키보드/마우스 활성화"),
("Enable Clipboard", "클립보드 활성화"),
("Enable File Transfer", "파일 전송 활성화"),
("Enable TCP Tunneling", "TCP 터널링 활성화"),
("IP Whitelisting", "IP 화이트리스트"),
("ID/Relay Server", "ID/Relay 서버"),
("Stop service", "서비스 중단"),
("Change ID", "ID 변경"),
("Website", "웹사이트"),
("About", "정보"),
("Mute", "음소거"),
("Audio Input", "오디오 입력"),
("Enhancements", ""),
("Hardware Codec", "하드웨어 코덱"),
("Adaptive Bitrate", "가변 비트레이트"),
("ID Server", "ID 서버"),
("Relay Server", "Relay 서버"),
("API Server", "API 서버"),
("invalid_http", "다음과 같이 시작해야 합니다. http:// 또는 https://"),
("Invalid IP", "유효하지 않은 IP"),
("id_change_tip", "a-z, A-Z, 0-9, _(밑줄 문자)만 입력 가능합니다. 첫 문자는 a-z 혹은 A-Z로 시작해야 합니다. 길이는 6 ~ 16글자가 요구됩니다."),
("Invalid format", "유효하지 않은 형식"),
("server_not_support", "해당 서버가 아직 지원하지 않습니다"),
("Not available", "불가능"),
("Too frequent", "너무 잦은 시도"),
("Cancel", "취소"),
("Skip", "넘기기"),
("Close", "닫기"),
("Retry", "재시도"),
("OK", "확인"),
("Password Required", "비밀번호 입력"),
("Please enter your password", "비밀번호를 입력해주세요"),
("Remember password", "이 비밀번호 기억하기"),
("Wrong Password", "틀린 비밀번호"),
("Do you want to enter again?", "다시 접속하시겠습니까?"),
("Connection Error", "연결 에러"),
("Error", "에러"),
("Reset by the peer", "다른 접속자에 의해 초기화됨"),
("Connecting...", "연결중..."),
("Connection in progress. Please wait.", "연결중입니다. 잠시만 기다려주세요."),
("Please try 1 minute later", "1분 뒤 다시 시도해주세요"),
("Login Error", "로그인 에러"),
("Successful", "성공"),
("Connected, waiting for image...", "연결됨. 이미지를 기다리는중..."),
("Name", "이름"),
("Type", "유형"),
("Modified", "수정됨"),
("Size", "크기"),
("Show Hidden Files", "숨김 파일 보기"),
("Receive", "받기"),
("Send", "보내기"),
("Refresh File", "파일 새로고침"),
("Local", "로컬"),
("Remote", "원격"),
("Remote Computer", "원격 컴퓨터"),
("Local Computer", "로컬 컴퓨터"),
("Confirm Delete", "삭제 재확인"),
("Delete", "삭제"),
("Properties", "속성"),
("Multi Select", "다중 선택"),
("Empty Directory", "빈 디렉터리"),
("Not an empty directory", "디렉터리가 비어있지 않습니다"),
("Are you sure you want to delete this file?", "정말로 해당 파일을 삭제하시겠습니까?"),
("Are you sure you want to delete this empty directory?", "정말로 비어있는 해당 디렉터리를 삭제하시겠습니까?"),
("Are you sure you want to delete the file of this directory?", "정말로 해당 파일 혹은 디렉터리를 삭제하시겠습니까?"),
("Do this for all conflicts", "모든 충돌에 대해 해당 작업 수행"),
("This is irreversible!", "해당 결정은 돌이킬 수 없습니다!"),
("Deleting", "삭제중"),
("files", "파일"),
("Waiting", "대기중"),
("Finished", "완료됨"),
("Speed", "속도"),
("Custom Image Quality", "이미지 품질 조정"),
("Privacy mode", "개인정보 보호 모드"),
("Block user input", "사용자 입력 차단"),
("Unblock user input", "사용자 입력 차단 해제"),
("Adjust Window", "화면 조정"),
("Original", "원본"),
("Shrink", "축소"),
("Stretch", "확대"),
("Good image quality", "최적 이미지 품질"),
("Balanced", "균형"),
("Optimize reaction time", "반응 시간 최적화"),
("Custom", "커스텀"),
("Show remote cursor", "원격 커서 보이기"),
("Show quality monitor", "품질 모니터 띄우기"),
("Disable clipboard", "클립보드 비활성화"),
("Lock after session end", "세션 종료 후 화면 잠금"),
("Insert", "입력"),
("Insert Lock", "입력 잠금"),
("Refresh", "새로고침"),
("ID does not exist", "ID가 존재하지 않습니다"),
("Failed to connect to rendezvous server", "rendezvous 서버에 접속을 실패하였습니다"),
("Please try later", "다시 시도해주세요"),
("Remote desktop is offline", "원격 데스크탑이 연결되어 있지 않습니다"),
("Key mismatch", "키가 일치하지 않습니다."),
("Timeout", "시간 초과"),
("Failed to connect to relay server", "relay 서버에 접속을 실패하였습니다"),
("Failed to connect via rendezvous server", "rendezvous 서버를 통한 접속에 실패하였습니다"),
("Failed to connect via relay server", "relay 서버를 통한 접속에 실패하였습니다"),
("Failed to make direct connection to remote desktop", "원격 데스크탑으로의 직접 연결 생성에 실패하였습니다"),
("Set Password", "비밀번호 설정"),
("OS Password", "OS 비밀번호"),
("install_tip", "UAC로 인해, RustDesk가 원격지일 때 일부 기능이 동작하지 않을 수 있습니다. UAC 문제를 방지하려면, 아래 버튼을 클릭하여 RustDesk를 시스템에 설치해주세요."),
("Click to upgrade", "클릭하여 업그레이드"),
("Click to download", "클릭하여 다운로드"),
("Click to update", "클릭하여 업데이트"),
("Configure", "구성"),
("config_acc", "당신의 데스크탑을 원격으로 제어하기 전에, RustDesk에게 \"Accessibility (접근성)\" 권한을 부여해야 합니다."),
("config_screen", "당신의 데스크탑을 원격으로 제어하기 전에, RustDesk에게 \"Screen Recording (화면 녹화)\" 권한을 부여해야 합니다."),
("Installing ...", "설치중 ..."),
("Install", "설치하기"),
("Installation", "설치"),
("Installation Path", "설치 경로"),
("Create start menu shortcuts", "시작 메뉴에 바로가기 생성"),
("Create desktop icon", "데스크탑 아이콘 생성"),
("agreement_tip", "설치를 시작하기 전에, 라이선스 약관에 동의를 해야합니다."),
("Accept and Install", "동의 및 설치"),
("End-user license agreement", "최종 사용자 라이선스 약관 동의"),
("Generating ...", "생성중 ..."),
("Your installation is lower version.", "설치 버전이 최신 버전이 아닙니다."),
("not_close_tcp_tip", "연결을 사용하는 동안 이 창을 끄지 마세요"),
("Listening ...", "연결 대기중 ..."),
("Remote Host", "원격 호스트"),
("Remote Port", "원격 포트"),
("Action", "액션"),
("Add", "추가"),
("Local Port", "로컬 포트"),
("setup_server_tip", "빠른 접속을 위해, 당신의 서버를 설정하세요"),
("Too short, at least 6 characters.", "너무 짧습니다, 최소 6글자 이상 입력해주세요."),
("The confirmation is not identical.", "확인용 입력이 일치하지 않습니다."),
("Permissions", "권한"),
("Accept", "수락"),
("Dismiss", "거부"),
("Disconnect", "연결 종료"),
("Allow using keyboard and mouse", "키보드와 마우스 허용"),
("Allow using clipboard", "클립보드 허용"),
("Allow hearing sound", "소리 듣기 허용"),
("Allow file copy and paste", "파일 복사 및 붙여넣기 허용"),
("Connected", "연결됨"),
("Direct and encrypted connection", "암호화된 직접 연결"),
("Relayed and encrypted connection", "암호화된 릴레이 연결"),
("Direct and unencrypted connection", "암호화되지 않은 직접 연결"),
("Relayed and unencrypted connection", "암호화되지 않은 릴레이 연결"),
("Enter Remote ID", "원격지 ID를 입력하세요"),
("Enter your password", "비밀번호를 입력하세요"),
("Logging in...", "로그인 중..."),
("Enable RDP session sharing", "RDP 세션 공유를 활성화하세요"),
("Auto Login", "자동 로그인"),
("Enable Direct IP Access", "IP 직접 접근 활성화하세요"),
("Rename", "이름 변경"),
("Space", "공간"),
("Create Desktop Shortcut", "데스크탑 바로가기 생성"),
("Change Path", "경로 변경"),
("Create Folder", "폴더 생성"),
("Please enter the folder name", "폴더명을 입력해주세요"),
("Fix it", "문제 해결"),
("Warning", "경고"),
("Login screen using Wayland is not supported", "Wayland를 사용한 로그인 화면이 지원되지 않습니다"),
("Reboot required", "재부팅이 필요합니다"),
("Unsupported display server ", "지원하지 않는 디스플레이 서버"),
("x11 expected", "x11 예상됨"),
("Port", "포트"),
("Settings", "설정"),
("Username", "사용자명"),
("Invalid port", "유효하지 않은 포트"),
("Closed manually by the peer", "다른 사용자에 의해 종료됨"),
("Enable remote configuration modification", "원격 구성 변경 활성화"),
("Run without install", "설치 없이 실행"),
("Always connected via relay", "항상 relay를 통해 접속됨"),
("Always connect via relay", "항상 relay를 통해 접속하기"),
("whitelist_tip", "화이트리스트에 있는 IP만 현 데스크탑에 접속 가능합니다"),
("Login", "로그인"),
("Logout", "로그아웃"),
("Tags", "태그"),
("Search ID", "ID 검색"),
("Current Wayland display server is not supported", "현재 Wayland 디스플레이 서버가 지원되지 않습니다"),
("whitelist_sep", "다음 글자로 구분합니다. ',(콤마) ;(세미콜론) 띄어쓰기 혹은 줄바꿈'"),
("Add ID", "ID 추가"),
("Add Tag", "태그 추가"),
("Unselect all tags", "모든 태그 선택 해제"),
("Network error", "네트워크 에러"),
("Username missed", "사용자명 누락"),
("Password missed", "비밀번호 누락"),
("Wrong credentials", "틀린 인증 정보"),
("Edit Tag", "태그 수정"),
("Unremember Password", "패스워드 기억하지 않기"),
("Favorites", "즐겨찾기"),
("Add to Favorites", "즐겨찾기에 추가"),
("Remove from Favorites", "즐겨찾기에서 삭제"),
("Empty", "비어 있음"),
("Invalid folder name", "유효하지 않은 폴더명"),
("Socks5 Proxy", "Socks5 프록시"),
("Hostname", "호스트명"),
("Discovered", "찾음"),
("install_daemon_tip", "부팅된 이후 시스템 서비스에 설치해야 합니다."),
("Remote ID", "원격지 ID"),
("Paste", "붙여넣기"),
("Paste here?", "여기에 붙여넣겠습니까?"),
("Are you sure to close the connection?", "정말로 연결을 종료하시겠습니까?"),
("Download new version", "최신 버전 다운로드"),
("Touch mode", "터치 모드"),
("Mouse mode", "마우스 모드"),
("One-Finger Tap", "한 손가락 탭"),
("Left Mouse", "왼쪽 마우스"),
("One-Long Tap", "길게 누르기"),
("Two-Finger Tap", "두 손가락 탭"),
("Right Mouse", "오른쪽 마우스"),
("One-Finger Move", "한 손가락 이동"),
("Double Tap & Move", "두 번 탭 하고 이동"),
("Mouse Drag", "마우스 드래그"),
("Three-Finger vertically", "세 손가락 세로로"),
("Mouse Wheel", "마우스 휠"),
("Two-Finger Move", "두 손가락 이동"),
("Canvas Move", "캔버스 이동"),
("Pinch to Zoom", "확대/축소"),
("Canvas Zoom", "캔버스 확대"),
("Reset canvas", "캔버스 초기화"),
("No permission of file transfer", "파일 전송 권한이 없습니다"),
("Note", "노트"),
("Connection", "연결"),
("Share Screen", "화면 공유"),
("CLOSE", "종료"),
("OPEN", "열기"),
("Chat", "채팅"),
("Total", "총합"),
("items", "개체"),
("Selected", "선택됨"),
("Screen Capture", "화면 캡처"),
("Input Control", "입력 제어"),
("Audio Capture", "오디오 캡처"),
("File Connection", "파일 전송"),
("Screen Connection", "화면 전송"),
("Do you accept?", "동의하십니까?"),
("Open System Setting", "시스템 설정 열기"),
("How to get Android input permission?", "안드로이드 입력 권한에 어떻게 접근합니까?"),
("android_input_permission_tip1", "원격지로서 마우스나 터치를 통해 Android 장치를 제어하려면 RustDesk에서 \"Accessibility (접근성)\" 서비스 사용을 허용해야 합니다."),
("android_input_permission_tip2", "시스템 설정 페이지로 이동하여 [설치된 서비스]에서 [RustDesk Input] 서비스를 켜십시오."),
("android_new_connection_tip", "현재 장치의 새로운 제어 요청이 수신되었습니다."),
("android_service_will_start_tip", "\"화면 캡처\"를 켜면 서비스가 자동으로 시작되어 다른 장치에서 사용자 장치에 대한 연결을 요청할 수 있습니다."),
("android_stop_service_tip", "서비스를 종료하면 모든 연결이 자동으로 닫힙니다."),
("android_version_audio_tip", "현재 Android 버전은 오디오 캡처를 지원하지 않습니다. Android 10 이상으로 업그레이드하십시오."),
("android_start_service_tip", "[서비스 시작] 또는 [화면 캡처] 권한을 눌러 화면 공유 서비스를 시작합니다."),
("Account", "계정"),
("Overwrite", "덮어쓰기"),
("This file exists, skip or overwrite this file?", "해당 파일이 이미 존재합니다, 넘어가거나 덮어쓰시겠습니까?"),
("Quit", "종료"),
("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"),
("Help", "지원"),
("Failed", "실패"),
("Succeeded", "성공"),
("Someone turns on privacy mode, exit", "누군가가 개인정보 보호 모드를 활성화하여 종료됩니다"),
("Unsupported", "지원되지 않음"),
("Peer denied", "다른 사용자에 의해 거부됨"),
("Please install plugins", "플러그인을 설치해주세요"),
("Peer exit", "다른 사용자가 나감"),
("Failed to turn off", "종료에 실패함"),
("Turned off", "종료됨"),
("In privacy mode", "개인정보 보호 모드 진입"),
("Out privacy mode", "개인정보 보호 모드 나감"),
("Language", "언어"),
("Keep RustDesk background service", "RustDesk 백그라운드 서비스로 유지하기"),
("Ignore Battery Optimizations", "배터리 최적화 무시하기"),
("android_open_battery_optimizations_tip", "해당 기능을 비활성화하려면 RustDesk 응용 프로그램 설정 페이지로 이동하여 [배터리]에서 [제한 없음] 선택을 해제하십시오."),
("Connection not allowed", "연결이 허용되지 않음"),
("Use temporary password", "임시 비밀번호 사용"),
("Use permanent password", "영구 비밀번호 사용"),
("Use both passwords", "두 비밀번호 (임시/영구) 사용"),
("Set permanent password", "영구 비밀번호 설정"),
("Set temporary password length", "임시 비밀번호 길이 설정"),
("Enable Remote Restart", "원격지 재시작 활성화"),
("Allow remote restart", "원격지 재시작 허용"),
("Restart Remote Device", "원격 기기 재시작"),
("Are you sure you want to restart", "정말로 재시작 하시겠습니까"),
("Restarting Remote Device", "원격 기기를 다시 시작하는중"),
("remote_restarting_tip", "원격 장치를 다시 시작하는 중입니다. 이 메시지 상자를 닫고 잠시 후 영구 비밀번호로 다시 연결하십시오."),
].iter().cloned().collect();
}

303
src/lang/pt_PT Normal file
View File

@ -0,0 +1,303 @@
lazy_static::lazy_static! {
pub static ref T: std::collections::HashMap<&'static str, &'static str> =
[
("Status", "Estado"),
("Your Desktop", "Ambiente de Trabalho"),
("desk_tip", "O seu Ambiente de Trabalho pode ser acedido com este ID e palavra-passe."),
("Password", "Senha"),
("Ready", "Pronto"),
("Established", "Estabelecido"),
("connecting_status", "A ligar à rede do RustDesk..."),
("Enable Service", "Activar Serviço"),
("Start Service", "Iniciar Serviço"),
("Service is running", "Serviço está activo"),
("Service is not running", "Serviço não está activo"),
("not_ready_status", "Indisponível. Por favor verifique a sua ligação"),
("Control Remote Desktop", "Controle o Ambiente de Trabalho à distância"),
("Transfer File", "Transferir Ficheiro"),
("Connect", "Ligar"),
("Recent Sessions", "Sessões recentes"),
("Address Book", "Lista de Endereços"),
("Confirmation", "Confirmação"),
("TCP Tunneling", "Túnel TCP"),
("Remove", "Remover"),
("Refresh random password", "Actualizar palavra-chave"),
("Set your own password", "Configure a sua palavra-passe"),
("Enable Keyboard/Mouse", "Activar Teclado/Rato"),
("Enable Clipboard", "Activar Área de Transferência"),
("Enable File Transfer", "Activar Transferência de Ficheiros"),
("Enable TCP Tunneling", "Activar Túnel TCP"),
("IP Whitelisting", "Whitelist de IP"),
("ID/Relay Server", "Servidor ID/Relay"),
("Stop service", "Parar serviço"),
("Change ID", "Alterar ID"),
("Website", "Website"),
("About", "Sobre"),
("Mute", "Emudecer"),
("Audio Input", "Entrada de Áudio"),
("Enhancements", "Melhorias"),
("Hardware Codec", ""),
("Adaptive Bitrate", ""),
("ID Server", "Servidor de ID"),
("Relay Server", "Servidor de Relay"),
("API Server", "Servidor da API"),
("invalid_http", "deve iniciar com http:// ou https://"),
("Invalid IP", "IP inválido"),
("id_change_tip", "Somente os caracteres a-z, A-Z, 0-9 e _ (sublinhado) são permitidos. A primeira letra deve ser a-z, A-Z. Comprimento entre 6 e 16."),
("Invalid format", "Formato inválido"),
("server_not_support", "Ainda não suportado pelo servidor"),
("Not available", "Indisponível"),
("Too frequent", "Muito frequente"),
("Cancel", "Cancelar"),
("Skip", "Passar"),
("Close", "Fechar"),
("Retry", "Tentar novamente"),
("OK", "Confirmar"),
("Password Required", "Palavra-chave Necessária"),
("Please enter your password", "Por favor introduza a sua palavra-chave"),
("Remember password", "Memorizar palavra-chave"),
("Wrong Password", "Palavra-chave inválida"),
("Do you want to enter again?", "Deseja tentar novamente??"),
("Connection Error", "Erro de Ligação"),
("Error", "Erro"),
("Reset by the peer", "Reiniciado pelo destino"),
("Connecting...", "A Ligar..."),
("Connection in progress. Please wait.", "Ligação em progresso. Aguarde por favor."),
("Please try 1 minute later", "Por favor tente após 1 minuto"),
("Login Error", "Erro de Login"),
("Successful", "Sucesso"),
("Connected, waiting for image...", "Ligado. A aguardar pela imagem..."),
("Name", "Nome"),
("Type", "Tipo"),
("Modified", "Modificado"),
("Size", "Tamanho"),
("Show Hidden Files", "Mostrar Ficheiros Ocultos"),
("Receive", "Receber"),
("Send", "Enviar"),
("Refresh File", "Actualizar Ficheiro"),
("Local", "Local"),
("Remote", "Remoto"),
("Remote Computer", "Computador Remoto"),
("Local Computer", "Computador Local"),
("Confirm Delete", "Confirmar Apagar"),
("Delete", "Apagar"),
("Properties", "Propriedades"),
("Multi Select", "Selecção Múltipla"),
("Empty Directory", "Directório Vazio"),
("Not an empty directory", "Directório não está vazio"),
("Are you sure you want to delete this file?", "Tem certeza que deseja apagar este ficheiro?"),
("Are you sure you want to delete this empty directory?", "Tem certeza que deseja apagar este directório vazio?"),
("Are you sure you want to delete the file of this directory?", "Tem certeza que deseja apagar este ficheiro deste directório?"),
("Do this for all conflicts", "Fazer isto para todos os conflictos"),
("This is irreversible!", "Isto é irreversível!"),
("Deleting", "A apagar"),
("files", "ficheiros"),
("Waiting", "A aguardar"),
("Finished", "Completo"),
("Speed", "Velocidade"),
("Custom Image Quality", "Qualidade Visual Personalizada"),
("Privacy mode", "Modo privado"),
("Block user input", "Bloquear entrada de utilizador"),
("Unblock user input", "Desbloquear entrada de utilizador"),
("Adjust Window", "Ajustar Janela"),
("Original", "Original"),
("Shrink", "Reduzir"),
("Stretch", "Aumentar"),
("Good image quality", "Qualidade visual boa"),
("Balanced", "Equilibrada"),
("Optimize reaction time", "Optimizar tempo de reacção"),
("Custom", "Personalizado"),
("Show remote cursor", "Mostrar cursor remoto"),
("Show quality monitor", ""),
("Disable clipboard", "Desabilitar área de transferência"),
("Lock after session end", "Bloquear após o fim da sessão"),
("Insert", "Inserir"),
("Insert Lock", "Bloquear Inserir"),
("Refresh", "Actualizar"),
("ID does not exist", "ID não existente"),
("Failed to connect to rendezvous server", "Falha ao ligar ao servidor de rendezvous"),
("Please try later", "Por favor tente mais tarde"),
("Remote desktop is offline", "Ambiente de trabalho remoto está desligado"),
("Key mismatch", "Chaves incompatíveis"),
("Timeout", "Tempo esgotado"),
("Failed to connect to relay server", "Falha ao ligar ao servidor de relay"),
("Failed to connect via rendezvous server", "Falha ao ligar ao servidor de rendezvous"),
("Failed to connect via relay server", "Falha ao ligar através do servidor de relay"),
("Failed to make direct connection to remote desktop", "Falha ao fazer ligação directa ao desktop remoto"),
("Set Password", "Definir palavra-chave"),
("OS Password", "Senha do SO"),
("install_tip", "Devido ao UAC, o RustDesk não funciona correctamente em alguns casos. Para evitar o UAC, por favor clique no botão abaixo para instalar o RustDesk no sistema."),
("Click to update", "Clique para fazer a actualização"),
("Click to download", "Clique para carregar"),
("Click to update", "Clique para fazer a actualização"),
("Configure", "Configurar"),
("config_acc", "Para controlar o seu Ambiente de Trabalho remotamente, é preciso conceder ao RustDesk permissões de \"Acessibilidade\"."),
("config_screen", "Para aceder ao seu Ambiente de Trabalho remotamente, é preciso conceder ao RustDesk permissões de \"Gravar a Tela\"/"),
("Installing ...", "A Instalar ..."),
("Install", "Instalar"),
("Installation", "Instalação"),
("Installation Path", "Caminho da Instalação"),
("Create start menu shortcuts", "Criar atalhos no menu iniciar"),
("Create desktop icon", "Criar ícone no ambiente de trabalho"),
("agreement_tip", "Ao iniciar a instalação, você concorda com o acordo de licença."),
("Accept and Install", "Aceitar e Instalar"),
("End-user license agreement", "Acordo de licença do utilizador final"),
("Generating ...", "A Gerar ..."),
("Your installation is lower version.", "A sua instalação é de uma versão anterior."),
("not_close_tcp_tip", "Não feche esta janela enquanto estiver a utilizar o túnel"),
("Listening ...", "A escuta ..."),
("Remote Host", "Host Remoto"),
("Remote Port", "Porta Remota"),
("Action", "Acção"),
("Add", "Adicionar"),
("Local Port", "Porta Local"),
("setup_server_tip", "Para uma ligação mais rápida, por favor configure seu próprio servidor"),
("Too short, at least 6 characters.", "Muito curto, pelo menos 6 caracteres."),
("The confirmation is not identical.", "A confirmação não é idêntica."),
("Permissions", "Permissões"),
("Accept", "Aceitar"),
("Dismiss", "Dispensar"),
("Disconnect", "Desconectar"),
("Allow using keyboard and mouse", "Permitir o uso de teclado e rato"),
("Allow using clipboard", "Permitir o uso da área de transferência"),
("Allow hearing sound", "Permitir ouvir som"),
("Allow file copy and paste", "Permitir copiar e mover ficheiros"),
("Connected", "Ligado"),
("Direct and encrypted connection", "Ligação directa e encriptada"),
("Relayed and encrypted connection", "Ligação via relay e encriptada"),
("Direct and unencrypted connection", "Ligação direta e não encriptada"),
("Relayed and unencrypted connection", "Ligação via relay e não encriptada"),
("Enter Remote ID", "Introduza o ID Remoto"),
("Enter your password", "Introduza a sua palavra-chave"),
("Logging in...", "A efectuar Login..."),
("Enable RDP session sharing", "Activar partilha de sessão RDP"),
("Auto Login", "Login Automático (Somente válido se você activou \"Bloquear após o fim da sessão\")"),
("Enable Direct IP Access", "Activar Acesso IP Directo"),
("Rename", "Renomear"),
("Space", "Espaço"),
("Create Desktop Shortcut", "Criar Atalho no Ambiente de Trabalho"),
("Change Path", "Alterar Caminho"),
("Create Folder", "Criar Diretório"),
("Please enter the folder name", "Por favor introduza o nome do diretório"),
("Fix it", "Reparar"),
("Warning", "Aviso"),
("Login screen using Wayland is not supported", "Tela de Login com Wayland não é suportada"),
("Reboot required", "Reinicialização necessária"),
("Unsupported display server ", "Servidor de display não suportado"),
("x11 expected", "x11 em falha"),
("Port", "Porta"),
("Settings", "Configurações"),
("Username", "Nome de utilizador"),
("Invalid port", "Porta inválida"),
("Closed manually by the peer", "Fechada manualmente pelo destino"),
("Enable remote configuration modification", "Habilitar modificações de configuração remotas"),
("Run without install", "Executar sem instalar"),
("Always connected via relay", "Sempre conectado via relay"),
("Always connect via relay", "Sempre conectar via relay"),
("whitelist_tip", "Somente IPs na whitelist podem me acessar"),
("Login", "Login"),
("Logout", "Sair"),
("Tags", "Tags"),
("Search ID", "Procurar ID"),
("Current Wayland display server is not supported", "Servidor de display Wayland atual não é suportado"),
("whitelist_sep", "Separado por vírcula, ponto-e-vírgula, espaços ou nova linha"),
("Add ID", "Adicionar ID"),
("Add Tag", "Adicionar Tag"),
("Unselect all tags", "Desselecionar todas as tags"),
("Network error", "Erro de rede"),
("Username missed", "Nome de utilizador em falta"),
("Password missed", "Palavra-chave em falta"),
("Wrong credentials", "Nome de utilizador ou palavra-chave incorrectos"),
("Edit Tag", "Editar Tag"),
("Unremember Password", "Esquecer Palavra-chave"),
("Favorites", "Favoritos"),
("Add to Favorites", "Adicionar aos Favoritos"),
("Remove from Favorites", "Remover dos Favoritos"),
("Empty", "Vazio"),
("Invalid folder name", "Nome de diretório inválido"),
("Socks5 Proxy", "Proxy Socks5"),
("Hostname", "Nome de anfitrião"),
("Discovered", "Descoberto"),
("install_daemon_tip", "Para inicialização junto do sistema, deve instalar o serviço de sistema."),
("Remote ID", "ID Remoto"),
("Paste", "Colar"),
("Paste here?", "Colar aqui?"),
("Are you sure to close the connection?", "Tem certeza que deseja fechar a ligação?"),
("Download new version", "Transferir nova versão"),
("Touch mode", "Modo toque"),
("Mouse mode", "Modo rato"),
("One-Finger Tap", "Toque com um dedo"),
("Left Mouse", "Botão esquerdo do rato"),
("One-Long Tap", "Um toque longo"),
("Two-Finger Tap", "Toque com dois dedos"),
("Right Mouse", "Botão direito do rato"),
("One-Finger Move", "Mover com um dedo"),
("Double Tap & Move", "Toque duplo & mover"),
("Mouse Drag", "Arrastar com o rato"),
("Three-Finger vertically", "Três dedos verticalmente"),
("Mouse Wheel", "Roda do rato"),
("Two-Finger Move", "Mover com dois dedos"),
("Canvas Move", "Mover Tela"),
("Pinch to Zoom", "Beliscar para Zoom"),
("Canvas Zoom", "Zoom na Tela"),
("Reset canvas", "Reiniciar tela"),
("No permission of file transfer", "Sem permissões de transferência de ficheiro"),
("Note", "Nota"),
("Connection", "Ligação"),
("Share Screen", "Partilhar ecran"),
("CLOSE", "FECHAR"),
("OPEN", "ABRIR"),
("Chat", "Conversar"),
("Total", "Total"),
("items", "itens"),
("Selected", "Seleccionado"),
("Screen Capture", "Captura de Ecran"),
("Input Control", "Controle de Entrada"),
("Audio Capture", "Captura de Áudio"),
("File Connection", "Ligação de Arquivo"),
("Screen Connection", "Ligação de Ecran"),
("Do you accept?", "Aceita?"),
("Open System Setting", "Abrir Configurações do Sistema"),
("How to get Android input permission?", "Como activar a permissão de entrada do Android?"),
("android_input_permission_tip1", "Para que um dispositivo remoto controle o seu dispositivo Android via rato ou toque, você precisa permitir que o RustDesk use o serviço \"Acessibilidade\"."),
("android_input_permission_tip2", "Por favor vá para a próxima página de configuração do sistema, encontre e entre [Serviços Instalados], ACTIVE o serviço [RustDesk Input]."),
("android_new_connection_tip", "Nova requisição de controle recebida, solicita o controle do seu dispositivo atual."),
("android_service_will_start_tip", "Activar a Captura de Ecran irá automaticamente inicializar o serviço, permitindo que outros dispositivos solicitem uma ligação deste dispositivo."),
("android_stop_service_tip", "Fechar o serviço irá automaticamente fechar todas as ligações estabelecidas."),
("android_version_audio_tip", "A versão atual do Android não suporta captura de áudio, por favor actualize para o Android 10 ou maior."),
("android_start_service_tip", "Toque [Iniciar Serviço] ou abra a permissão [Captura de Ecran] para iniciar o serviço de partilha de ecran."),
("Account", "Conta"),
("Overwrite", "Substituir"),
("This file exists, skip or overwrite this file?", "Este ficheiro já existe, ignorar ou substituir este ficheiro?"),
("Quit", "Saída"),
("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"),
("Help", "Ajuda"),
("Failed", "Falhou"),
("Succeeded", "Conseguiu"),
("Someone turns on privacy mode, exit", "Alguém activou o modo de privacidade, desligue"),
("Unsupported", "Sem suporte"),
("Peer denied", "Remoto negado"),
("Please install plugins", "Por favor instale plugins"),
("Peer exit", "Saída do Remoto"),
("Failed to turn off", "Falha ao desligar"),
("Turned off", "Desligado"),
("In privacy mode", "Em modo de privacidade"),
("Out privacy mode", "Sair do modo de privacidade"),
("Language", "Linguagem"),
("Keep RustDesk background service", "Manter o serviço RustDesk em funcionamento"),
("Ignore Battery Optimizations", "Ignorar optimizações de Bateria"),
("android_open_battery_optimizations_tip", ""),
("Connection not allowed", "Ligação não autorizada"),
("Use temporary password", "Utilizar palavra-chave temporária"),
("Use permanent password", "Utilizar palavra-chave permanente"),
("Use both passwords", "Utilizar ambas as palavras-chave"),
("Set permanent password", "Definir palavra-chave permanente"),
("Set temporary password length", "Definir tamanho de palavra-chave temporária"),
("Enable Remote Restart", "Activar reiniciar remoto"),
("Allow remote restart", "Permitir reiniciar remoto"),
("Restart Remote Device", "Reiniciar Dispositivo Remoto"),
("Are you sure you want to restart", "Tem a certeza que pretende reiniciar"),
("Restarting Remote Device", "A reiniciar sistema remoto"),
("remote_restarting_tip", ""),
].iter().cloned().collect();
}

View File

@ -166,7 +166,7 @@ fn main() {
} }
fn import_config(path: &str) { fn import_config(path: &str) {
use hbb_common::{config::*, get_modified_time}; use hbb_common::{config::*, get_exe_time, get_modified_time};
let path2 = path.replace(".toml", "2.toml"); let path2 = path.replace(".toml", "2.toml");
let path2 = std::path::Path::new(&path2); let path2 = std::path::Path::new(&path2);
let path = std::path::Path::new(path); let path = std::path::Path::new(path);
@ -176,7 +176,9 @@ fn import_config(path: &str) {
log::info!("Empty source config, skipped"); log::info!("Empty source config, skipped");
return; return;
} }
if get_modified_time(&path) > get_modified_time(&Config::file()) { if get_modified_time(&path) > get_modified_time(&Config::file())
&& get_modified_time(&path) < get_exe_time()
{
if store_path(Config::file(), config).is_err() { if store_path(Config::file(), config).is_err() {
log::info!("config written"); log::info!("config written");
} }

View File

@ -1,7 +1,7 @@
use crate::client::*; use crate::client::*;
use hbb_common::{ use hbb_common::{
allow_err, bail, allow_err, bail,
config::CONNECT_TIMEOUT, config::READ_TIMEOUT,
futures::{SinkExt, StreamExt}, futures::{SinkExt, StreamExt},
log, log,
message_proto::*, message_proto::*,
@ -105,22 +105,61 @@ async fn connect_and_login(
key: &str, key: &str,
token: &str, token: &str,
is_rdp: bool, is_rdp: bool,
) -> ResultType<Option<Stream>> {
let mut res = connect_and_login_2(
id,
password,
ui_receiver,
interface.clone(),
forward,
key,
token,
is_rdp,
)
.await;
if res.is_err() && interface.is_force_relay() {
res = connect_and_login_2(
id,
password,
ui_receiver,
interface,
forward,
key,
token,
is_rdp,
)
.await;
}
res
}
async fn connect_and_login_2(
id: &str,
password: &str,
ui_receiver: &mut mpsc::UnboundedReceiver<Data>,
interface: impl Interface,
forward: &mut Framed<TcpStream, BytesCodec>,
key: &str,
token: &str,
is_rdp: bool,
) -> ResultType<Option<Stream>> { ) -> ResultType<Option<Stream>> {
let conn_type = if is_rdp { let conn_type = if is_rdp {
ConnType::RDP ConnType::RDP
} else { } else {
ConnType::PORT_FORWARD ConnType::PORT_FORWARD
}; };
let (mut stream, _) = Client::start(id, key, token, conn_type).await?; let (mut stream, direct) = Client::start(id, key, token, conn_type, interface.clone()).await?;
let mut interface = interface; let mut interface = interface;
let mut buffer = Vec::new(); let mut buffer = Vec::new();
let mut received = false;
loop { loop {
tokio::select! { tokio::select! {
res = timeout(CONNECT_TIMEOUT, stream.next()) => match res { res = timeout(READ_TIMEOUT, stream.next()) => match res {
Err(_) => { Err(_) => {
bail!("Timeout"); bail!("Timeout");
} }
Ok(Some(Ok(bytes))) => { Ok(Some(Ok(bytes))) => {
received = true;
let msg_in = Message::parse_from_bytes(&bytes)?; let msg_in = Message::parse_from_bytes(&bytes)?;
match msg_in.union { match msg_in.union {
Some(message::Union::Hash(hash)) => { Some(message::Union::Hash(hash)) => {
@ -143,6 +182,11 @@ async fn connect_and_login(
_ => {} _ => {}
} }
} }
Ok(Some(Err(err))) => {
log::error!("Connection closed: {}", err);
interface.set_force_relay(direct, received);
bail!("Connection closed: {}", err);
}
_ => { _ => {
bail!("Reset by the peer"); bail!("Reset by the peer");
} }

View File

@ -316,7 +316,7 @@ class SessionList: Reactor.Component {
<li #connect>{translate('Connect')}</li> <li #connect>{translate('Connect')}</li>
<li #transfer>{translate('Transfer File')}</li> <li #transfer>{translate('Transfer File')}</li>
<li #tunnel>{translate('TCP Tunneling')}</li> <li #tunnel>{translate('TCP Tunneling')}</li>
{false && !handler.using_public_server() && <li #force-always-relay><span>{svg_checkmark}</span>{translate('Always connect via relay')}</li>} <li #force-always-relay><span>{svg_checkmark}</span>{translate('Always connect via relay')}</li>
<li #rdp>RDP<EditRdpPort /></li> <li #rdp>RDP<EditRdpPort /></li>
<li #wol>{translate('WOL')}</li> <li #wol>{translate('WOL')}</li>
<div .separator /> <div .separator />
@ -396,7 +396,6 @@ class SessionList: Reactor.Component {
if (el) { if (el) {
var force = handler.get_peer_option(id, "force-always-relay"); var force = handler.get_peer_option(id, "force-always-relay");
el.attributes.toggleClass("selected", force == "Y"); el.attributes.toggleClass("selected", force == "Y");
el.attributes.toggleClass("line-through", force != "Y");
} }
var conn = this.$(menu #connect); var conn = this.$(menu #connect);
if (conn) { if (conn) {

View File

@ -3,7 +3,7 @@ stdout.println("current platform:", OS);
stdout.println("is_xfce: ", is_xfce); stdout.println("is_xfce: ", is_xfce);
// html min-width, min-height not working on mac, below works for all // html min-width, min-height not working on mac, below works for all
view.windowMinSize = (scaleIt(500), scaleIt(300)); view.windowMinSize = (scaleIt(560), scaleIt(300));
var app; var app;
var tmp = handler.get_connect_status(); var tmp = handler.get_connect_status();

View File

@ -13,6 +13,7 @@ use objc::{
}; };
use sciter::{make_args, Host}; use sciter::{make_args, Host};
use std::{ffi::c_void, rc::Rc}; use std::{ffi::c_void, rc::Rc};
use dark_light;
static APP_HANDLER_IVAR: &str = "GoDeskAppHandler"; static APP_HANDLER_IVAR: &str = "GoDeskAppHandler";
@ -233,7 +234,17 @@ pub fn make_tray() {
set_delegate(None); set_delegate(None);
} }
use tray_item::TrayItem; use tray_item::TrayItem;
if let Ok(mut tray) = TrayItem::new(&crate::get_app_name(), "mac-tray.png") { let mode = dark_light::detect();
let mut icon_path = "";
match mode {
dark_light::Mode::Dark => {
icon_path = "mac-tray-light.png";
},
dark_light::Mode::Light => {
icon_path = "mac-tray-dark.png";
},
}
if let Ok(mut tray) = TrayItem::new(&crate::get_app_name(), icon_path) {
tray.add_label(&format!( tray.add_label(&format!(
"{} {}", "{} {}",
crate::get_app_name(), crate::get_app_name(),

View File

@ -49,6 +49,7 @@ use crate::{
client::*, client::*,
common::{self, check_clipboard, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL}, common::{self, check_clipboard, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL},
}; };
use errno;
type Video = AssetPtr<video_destination>; type Video = AssetPtr<video_destination>;
@ -1452,12 +1453,21 @@ impl Remote {
async fn io_loop(&mut self, key: &str, token: &str) { async fn io_loop(&mut self, key: &str, token: &str) {
let stop_clipboard = self.start_clipboard(); let stop_clipboard = self.start_clipboard();
let mut last_recv_time = Instant::now(); let mut last_recv_time = Instant::now();
let mut received = false;
let conn_type = if self.handler.is_file_transfer() { let conn_type = if self.handler.is_file_transfer() {
ConnType::FILE_TRANSFER ConnType::FILE_TRANSFER
} else { } else {
ConnType::default() ConnType::default()
}; };
match Client::start(&self.handler.id, key, token, conn_type).await { match Client::start(
&self.handler.id,
key,
token,
conn_type,
self.handler.clone(),
)
.await
{
Ok((mut peer, direct)) => { Ok((mut peer, direct)) => {
SERVER_KEYBOARD_ENABLED.store(true, Ordering::SeqCst); SERVER_KEYBOARD_ENABLED.store(true, Ordering::SeqCst);
SERVER_CLIPBOARD_ENABLED.store(true, Ordering::SeqCst); SERVER_CLIPBOARD_ENABLED.store(true, Ordering::SeqCst);
@ -1480,11 +1490,13 @@ impl Remote {
match res { match res {
Err(err) => { Err(err) => {
log::error!("Connection closed: {}", err); log::error!("Connection closed: {}", err);
self.handler.set_force_relay(direct, received);
self.handler.msgbox("error", "Connection Error", &err.to_string()); self.handler.msgbox("error", "Connection Error", &err.to_string());
break; break;
} }
Ok(ref bytes) => { Ok(ref bytes) => {
last_recv_time = Instant::now(); last_recv_time = Instant::now();
received = true;
self.data_count.fetch_add(bytes.len(), Ordering::Relaxed); self.data_count.fetch_add(bytes.len(), Ordering::Relaxed);
if !self.handle_msg_from_peer(bytes, &mut peer).await { if !self.handle_msg_from_peer(bytes, &mut peer).await {
break break
@ -2067,6 +2079,22 @@ impl Remote {
true true
} }
async fn send_opts_after_login(&self, peer: &mut Stream) {
if let Some(opts) = self
.handler
.lc
.read()
.unwrap()
.get_option_message_after_login()
{
let mut misc = Misc::new();
misc.set_option(opts);
let mut msg_out = Message::new();
msg_out.set_misc(misc);
allow_err!(peer.send(&msg_out).await);
}
}
async fn handle_msg_from_peer(&mut self, data: &[u8], peer: &mut Stream) -> bool { async fn handle_msg_from_peer(&mut self, data: &[u8], peer: &mut Stream) -> bool {
if let Ok(msg_in) = Message::parse_from_bytes(&data) { if let Ok(msg_in) = Message::parse_from_bytes(&data) {
match msg_in.union { match msg_in.union {
@ -2075,7 +2103,7 @@ impl Remote {
self.first_frame = true; self.first_frame = true;
self.handler.call2("closeSuccess", &make_args!()); self.handler.call2("closeSuccess", &make_args!());
self.handler.call("adaptSize", &make_args!()); self.handler.call("adaptSize", &make_args!());
common::send_opts_after_login(&self.handler.lc.read().unwrap(), peer).await; self.send_opts_after_login(peer).await;
} }
let incomming_format = CodecFormat::from(&vf); let incomming_format = CodecFormat::from(&vf);
if self.video_format != incomming_format { if self.video_format != incomming_format {
@ -2639,7 +2667,7 @@ impl Interface for Handler {
self.lc.write().unwrap().handle_peer_info(username, pi); self.lc.write().unwrap().handle_peer_info(username, pi);
self.call("updatePrivacyMode", &[]); self.call("updatePrivacyMode", &[]);
self.call("updatePi", &make_args!(pi_sciter)); self.call("updatePi", &make_args!(pi_sciter));
if self.is_file_transfer() || self.is_port_forward() { if self.is_file_transfer() {
self.call2("closeSuccess", &make_args!()); self.call2("closeSuccess", &make_args!());
} else if !self.is_port_forward() { } else if !self.is_port_forward() {
self.msgbox("success", "Successful", "Connected, waiting for image..."); self.msgbox("success", "Successful", "Connected, waiting for image...");
@ -2675,6 +2703,24 @@ impl Interface for Handler {
handle_test_delay(t, peer).await; handle_test_delay(t, peer).await;
} }
} }
fn set_force_relay(&mut self, direct: bool, received: bool) {
let mut lc = self.lc.write().unwrap();
lc.force_relay = false;
if direct && !received {
let errno = errno::errno().0;
log::info!("errno is {}", errno);
// TODO: check mac and ios
if cfg!(windows) && errno == 10054 || !cfg!(windows) && errno == 104 {
lc.force_relay = true;
lc.set_option("force-always-relay".to_owned(), "Y".to_owned());
}
}
}
fn is_force_relay(&self) -> bool {
self.lc.read().unwrap().force_relay
}
} }
impl Handler { impl Handler {