Merge branch 'master' into master
This commit is contained in:
commit
6db3a2e85c
Cargo.lockCargo.tomlREADME-AR.mdREADME-CS.mdREADME-DE.mdREADME-EO.mdREADME-ES.mdREADME-FA.mdREADME-FI.mdREADME-FR.mdREADME-HU.mdREADME-ID.mdREADME-IT.mdREADME-JP.mdREADME-KR.mdREADME-ML.mdREADME-NL.mdREADME-PL.mdREADME-PTBR.mdREADME-RU.mdREADME-ZH.mdREADME.md
flutter
android/app/src/main
lib
libs/hbb_common
rust-toolchain.tomlsrc
852
Cargo.lock
generated
852
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
17
Cargo.toml
17
Cargo.toml
@ -51,11 +51,13 @@ samplerate = { version = "0.2", optional = true }
|
|||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
uuid = { version = "1.0", features = ["v4"] }
|
uuid = { version = "1.0", features = ["v4"] }
|
||||||
clap = "3.0"
|
clap = "3.0"
|
||||||
rpassword = "6.0"
|
rpassword = "7.0"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
sysinfo = "0.23"
|
sysinfo = "0.24"
|
||||||
num_cpus = "1.13"
|
num_cpus = "1.13"
|
||||||
bytes = "1.1"
|
bytes = "1.1"
|
||||||
|
default-net = "0.11.0"
|
||||||
|
wol-rs = "0.9.1"
|
||||||
|
|
||||||
[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 }
|
||||||
@ -77,9 +79,8 @@ arboard = "2.0"
|
|||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
#systray = { git = "https://github.com/open-trade/systray-rs" }
|
#systray = { git = "https://github.com/open-trade/systray-rs" }
|
||||||
trayicon = { version = "0.1", features = ["winit"] }
|
trayicon = { git = "https://github.com/open-trade/trayicon-rs", features = ["winit"] }
|
||||||
# > 0.25 not work with trayicon
|
winit = "0.26"
|
||||||
winit = "0.25"
|
|
||||||
winapi = { version = "0.3", features = ["winuser"] }
|
winapi = { version = "0.3", features = ["winuser"] }
|
||||||
winreg = "0.10"
|
winreg = "0.10"
|
||||||
windows-service = "0.4"
|
windows-service = "0.4"
|
||||||
@ -102,10 +103,10 @@ async-process = "1.3"
|
|||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
android_logger = "0.11"
|
android_logger = "0.11"
|
||||||
jni = "0.19.0"
|
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 = "1.30.0"
|
flutter_rust_bridge = "=1.30.0"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/simple_rc"]
|
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/simple_rc"]
|
||||||
@ -123,7 +124,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 = "1.30.0"
|
flutter_rust_bridge_codegen = "=1.30.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hound = "3.4"
|
hound = "3.4"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structure</a> •
|
<a href="#file-structure">Structure</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b> لغتك الأم, <a href="https://github.com/rustdesk/doc.rustdesk.com">Doc</a> و <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a>, README نحن بحاجة إلى مساعدتك لترجمة هذا </b>
|
<b> لغتك الأم, <a href="https://github.com/rustdesk/doc.rustdesk.com">Doc</a> و <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a>, README نحن بحاجة إلى مساعدتك لترجمة هذا </b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Struktura</a> •
|
<a href="#file-structure">Struktura</a> •
|
||||||
<a href="#snapshot">Ukázky</a><br>
|
<a href="#snapshot">Ukázky</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Potřebujeme Vaši pomoc s překláním textů tohoto ČTIMNE, <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">uživatelského rozhraní aplikace RustDesk</a> a <a href="https://github.com/rustdesk/doc.rustdesk.com">dokumentace k ní</a> do vašeho jazyka</b>
|
<b>Potřebujeme Vaši pomoc s překláním textů tohoto ČTIMNE, <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">uživatelského rozhraní aplikace RustDesk</a> a <a href="https://github.com/rustdesk/doc.rustdesk.com">dokumentace k ní</a> do vašeho jazyka</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#auf-docker-kompilieren">Docker</a> •
|
<a href="#auf-docker-kompilieren">Docker</a> •
|
||||||
<a href="#dateistruktur">Dateistruktur</a> •
|
<a href="#dateistruktur">Dateistruktur</a> •
|
||||||
<a href="#screenshots">Screenshots</a><br>
|
<a href="#screenshots">Screenshots</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Wir brauchen deine Hilfe um diese README Datei zu verbessern und aktualisieren</b>
|
<b>Wir brauchen deine Hilfe um diese README Datei zu verbessern und aktualisieren</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Rede mit uns: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Rede mit uns: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#kiel-kompili-kun-docker">Docker</a> •
|
<a href="#kiel-kompili-kun-docker">Docker</a> •
|
||||||
<a href="#dosierstrukturo">Strukturo</a> •
|
<a href="#dosierstrukturo">Strukturo</a> •
|
||||||
<a href="#ekrankopio">Ekrankopio</a><br>
|
<a href="#ekrankopio">Ekrankopio</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Ni bezonas helpon traduki tiun README kaj <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">la interfacon</a> al via denaska lingvo</b>
|
<b>Ni bezonas helpon traduki tiun README kaj <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">la interfacon</a> al via denaska lingvo</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Babili kun ni: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Babili kun ni: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#como-compilar-con-docker">Docker</a> •
|
<a href="#como-compilar-con-docker">Docker</a> •
|
||||||
<a href="#estructura-de-archivos">Estructura</a> •
|
<a href="#estructura-de-archivos">Estructura</a> •
|
||||||
<a href="#captura-de-pantalla">Captura de pantalla</a><br>
|
<a href="#captura-de-pantalla">Captura de pantalla</a><br>
|
||||||
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Necesitamos tu ayuda para traducir este README a tu idioma</b>
|
<b>Necesitamos tu ayuda para traducir este README a tu idioma</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a dir="rtl" href="#نحوه-ساخت-با-داکر">داکر</a> •
|
<a dir="rtl" href="#نحوه-ساخت-با-داکر">داکر</a> •
|
||||||
<a dir="rtl" href="#ساخت">ساخت</a> •
|
<a dir="rtl" href="#ساخت">ساخت</a> •
|
||||||
<a dir="rtl" href="#سرورهای-عمومی-رایگان">سرور</a><br>
|
<a dir="rtl" href="#سرورهای-عمومی-رایگان">سرور</a><br>
|
||||||
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
‫<b>برای ترجمه این <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang"> RustDesk UI</a> ،README و <a href="https://github.com/rustdesk/doc.rustdesk.com">Doc</a> به زبان مادری شما به کمکتون نیاز داریم
|
‫<b>برای ترجمه این <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang"> RustDesk UI</a> ،README و <a href="https://github.com/rustdesk/doc.rustdesk.com">Doc</a> به زبان مادری شما به کمکتون نیاز داریم
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Rakenne</a> •
|
<a href="#file-structure">Rakenne</a> •
|
||||||
<a href="#snapshot">Tilannevedos</a><br>
|
<a href="#snapshot">Tilannevedos</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Tarvitsemme apua tämän README-tiedoston kääntämiseksi äidinkielellesi</b>
|
<b>Tarvitsemme apua tämän README-tiedoston kääntämiseksi äidinkielellesi</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Juttele meidän kanssa: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Juttele meidän kanssa: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#comment-construire-avec-docker">Docker</a> -
|
<a href="#comment-construire-avec-docker">Docker</a> -
|
||||||
<a href="#structure-du-projet">Structure</a> -
|
<a href="#structure-du-projet">Structure</a> -
|
||||||
<a href="#images">Images</a><br>
|
<a href="#images">Images</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Nous avons besoin de votre aide pour traduire ce README dans votre langue maternelle</b>.
|
<b>Nous avons besoin de votre aide pour traduire ce README dans votre langue maternelle</b>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Chattez avec nous : [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Chattez avec nous : [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
182
README-HU.md
Normal file
182
README-HU.md
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img src="logo-header.svg" alt="RustDesk - Your remote desktop"><br>
|
||||||
|
<a href="#ingyenes-publikus-szerverek">Szerverek</a> •
|
||||||
|
<a href="#építési-pontok">Építés</a> •
|
||||||
|
<a href="#hogyan-éptís-dockerrel">Docker</a> •
|
||||||
|
<a href="#fájl-struktúra">Struktúra</a> •
|
||||||
|
<a href="#képernyőképek">Képernyőképek</a><br>
|
||||||
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
|
<b>Kell a segítséged, hogy lefordítsuk ezt a README-t, <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">a RustDesk UI-t</a> és a <a href="https://github.com/rustdesk/doc.rustdesk.com">Dokumentációt</a> az anyanyelvedre</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Beszélgess velünk: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
A RustDesk egy távoli elérésű asztali szoftver, Rust-ban írva. Működik mindenféle konfiguráció nélkül, feltelepítéssel, vagy anélkül. Az adataidat teljesen te kezeled, nincs szükség aggódásra a harmadik felek miatt. Használhatod a RustDesk punblikus randevú/relay szervereit, [hostolhatsz sajátot](https://rustdesk.com/server), vagy akár [írhatsz is egyet](https://github.com/rustdesk/rustdesk-server-demo).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
A RustDesk szívesen fogad minden contributiont, támogatást mindenkitől. Lásd a [`CONTRIBUTING.md`](CONTRIBUTING.md) fájlt a kezdéshez.
|
||||||
|
|
||||||
|
[**Hogyan működik a RustDesk?**](https://github.com/rustdesk/rustdesk/wiki/How-does-RustDesk-work%3F)
|
||||||
|
|
||||||
|
[**BINARY LELTÖLTÉS**](https://github.com/rustdesk/rustdesk/releases)
|
||||||
|
|
||||||
|
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||||
|
alt="Get it on F-Droid"
|
||||||
|
height="80">](https://f-droid.org/en/packages/com.carriez.flutter_hbb)
|
||||||
|
|
||||||
|
## Ingyenes publikus szerverek
|
||||||
|
|
||||||
|
Ezalatt az üzenet alatt találhatóak azok a publikus szerverek, amelyeket ingyen használhatsz. Ezek a szerverek változhatnak a jövőben, illetve a hálózatuk lehet hogy lassú lehet.
|
||||||
|
| Hely | Host | Specifikáció |
|
||||||
|
| --------- | ------------- | ------------------ |
|
||||||
|
| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
|
||||||
|
| Singapore | Vultr | 1 VCPU / 1GB RAM |
|
||||||
|
| Dallas | Vultr | 1 VCPU / 1GB RAM | |
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Az asztali verziók [sciter](https://sciter.com/)-t használnak a GUI-hoz, kérlek telepítsd a dynamikus könyvtárat magad.
|
||||||
|
|
||||||
|
[Windows](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x64/sciter.dll) |
|
||||||
|
[Linux](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so) |
|
||||||
|
[MacOS](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.osx/libsciter.dylib)
|
||||||
|
|
||||||
|
A telefonos verziók Flutter-t hasznának. Később lehetséges hogy Sciterről Flutterre migrálunk az asztali verziókban is.
|
||||||
|
|
||||||
|
## Építési pontok
|
||||||
|
|
||||||
|
- Készítsd elő a Rust, C++ fejlesztői környezetet (env)
|
||||||
|
|
||||||
|
- Telepítsd a [vcpkg](https://github.com/microsoft/vcpkg)-t, és állítsd be a `VCPKG_ROOT` környezeti változót helyesen
|
||||||
|
|
||||||
|
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static
|
||||||
|
- Linux/MacOS: vcpkg install libvpx libyuv opus
|
||||||
|
|
||||||
|
- Futtasd a `cargo run` parancsot
|
||||||
|
|
||||||
|
## [Építés](https://rustdesk.com/docs/hu/dev/build/)
|
||||||
|
|
||||||
|
## Hogyan építs Linuxon
|
||||||
|
|
||||||
|
### Ubuntu 18 (Debian 10)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fedora 28 (CentOS 8)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libxdo-devel libXfixes-devel pulseaudio-libs-devel cmake alsa-lib-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arch (Manjaro)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio
|
||||||
|
```
|
||||||
|
|
||||||
|
### Telepítsd a pynput csomagot
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pip3 install pynput
|
||||||
|
```
|
||||||
|
|
||||||
|
### Telepítsd a vcpkg-t
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/microsoft/vcpkg
|
||||||
|
cd vcpkg
|
||||||
|
git checkout 2021.12.01
|
||||||
|
cd ..
|
||||||
|
vcpkg/bootstrap-vcpkg.sh
|
||||||
|
export VCPKG_ROOT=$HOME/vcpkg
|
||||||
|
vcpkg/vcpkg install libvpx libyuv opus
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fixeld a libvpx-t (Fedora-n csak)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd vcpkg/buildtrees/libvpx/src
|
||||||
|
cd *
|
||||||
|
./configure
|
||||||
|
sed -i 's/CFLAGS+=-I/CFLAGS+=-fPIC -I/g' Makefile
|
||||||
|
sed -i 's/CXXFLAGS+=-I/CXXFLAGS+=-fPIC -I/g' Makefile
|
||||||
|
make
|
||||||
|
cp libvpx.a $HOME/vcpkg/installed/x64-linux/lib/
|
||||||
|
cd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Építés
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
|
source $HOME/.cargo/env
|
||||||
|
git clone https://github.com/rustdesk/rustdesk
|
||||||
|
cd rustdesk
|
||||||
|
mkdir -p target/debug
|
||||||
|
wget https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so
|
||||||
|
mv libsciter-gtk.so target/debug
|
||||||
|
VCPKG_ROOT=$HOME/vcpkg cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Válts Wayland-ról X11-re (Xorg)
|
||||||
|
|
||||||
|
A RustDesk nem támogatja a Waylendet. [Itt](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) található egy tutorial amelynek segítségével beállíthatod a Xorg-ot mint alap GNOME session.
|
||||||
|
|
||||||
|
## Hogyan építs Dockerrel
|
||||||
|
|
||||||
|
Kezdjünk a repo clónozásával, majd pedig a Docker container megépítésével:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/rustdesk/rustdesk
|
||||||
|
cd rustdesk
|
||||||
|
docker build -t "rustdesk-builder" .
|
||||||
|
```
|
||||||
|
|
||||||
|
Ezután, minden egyes alkalommal amikor meg kell építened a RustDesk-et, futtasd a kövezkező parancsot:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
|
||||||
|
```
|
||||||
|
|
||||||
|
Fontos, hogy az első építés lehet hogy több ideig fog tartani mint a következőek, mivel a dependenciek még nincsenek cachelve. Emelett, ha esetleg szeretnél valamilyen argumentumot hozzáadni az építő parancshoz, akkor megteheted a paracssor végén, a `<OPTIONAL-ARGS>` argumentum használatával. Például ha egy optimalizált release éptést szeretnél megépíteni, akkor add hozzá a fenti parancsorhoz a `--release` opciót. A futtatható binary elérhető lesz a target mappában a rendszereden, futtatni a következőképpen tudod:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
target/debug/rustdesk
|
||||||
|
```
|
||||||
|
|
||||||
|
Vagy ha release binary, akkor:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
target/release/rustdesk
|
||||||
|
```
|
||||||
|
|
||||||
|
Kérlek mindenképpen nézd meg hogy ezeket a parancsokat a root RustDesk mappában futtatod e, különben a RustDesk lehet hogy nem fogja megtalálni az építéshez szükséges elemeket. Fontos az is, hogy jelenleg más cargo subparancsok, például `install`vagy `run` nem támogatottak, mivel egy Dockeres építés esetén elindítanák a programot a containeren belül.
|
||||||
|
|
||||||
|
|
||||||
|
## Fájl Struktúra
|
||||||
|
|
||||||
|
- **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: video codec, config, tcp/udp wrapper, protobuf, fs functions for file transfer, and some other utility functions
|
||||||
|
- **[libs/scrap](https://github.com/rustdesk/rustdesk/tree/master/libs/scrap)**: screen capture
|
||||||
|
- **[libs/enigo](https://github.com/rustdesk/rustdesk/tree/master/libs/enigo)**: platform specific keyboard/mouse control
|
||||||
|
- **[src/ui](https://github.com/rustdesk/rustdesk/tree/master/src/ui)**: GUI
|
||||||
|
- **[src/server](https://github.com/rustdesk/rustdesk/tree/master/src/server)**: audio/clipboard/input/video services, and network connections
|
||||||
|
- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: start a peer connection
|
||||||
|
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: Communicate with [rustdesk-server](https://github.com/rustdesk/rustdesk-server), wait for remote direct (TCP hole punching) or relayed connection
|
||||||
|
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: platform specific code
|
||||||
|
- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: Flutter code for mobile
|
||||||
|
- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: Javascript for Flutter web client
|
||||||
|
|
||||||
|
## Képernyőképek
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
@ -5,11 +5,11 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structure</a> •
|
<a href="#file-structure">Structure</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Kami membutuhkan bantuan Anda untuk menerjemahkan README ini dan <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a> ke bahasa asli anda</b>
|
<b>Kami membutuhkan bantuan Anda untuk menerjemahkan README ini dan <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a> ke bahasa asli anda</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Birbincang bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Birbincang bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#come-compilare-con-docker">Docker</a> •
|
<a href="#come-compilare-con-docker">Docker</a> •
|
||||||
<a href="#struttura-dei-file">Struttura</a> •
|
<a href="#struttura-dei-file">Struttura</a> •
|
||||||
<a href="#screenshots">Screenshots</a><br>
|
<a href="#screenshots">Screenshots</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Abbiamo bisogno del tuo aiuto per tradurre questo README e la <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a> nella tua lingua nativa</b>
|
<b>Abbiamo bisogno del tuo aiuto per tradurre questo README e la <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a> nella tua lingua nativa</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Chatta con noi: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Chatta con noi: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structure</a> •
|
<a href="#file-structure">Structure</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>このREADMEをあなたの母国語に翻訳するために、あなたの助けが必要です。</b>
|
<b>このREADMEをあなたの母国語に翻訳するために、あなたの助けが必要です。</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structure</a> •
|
<a href="#file-structure">Structure</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>README를 모국어로 번역하기 위한 당신의 도움의 필요합니다.</b>
|
<b>README를 모국어로 번역하기 위한 당신의 도움의 필요합니다.</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structure</a> •
|
<a href="#file-structure">Structure</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>ഈ README നിങ്ങളുടെ മാതൃഭാഷയിലേക്ക് വിവർത്തനം ചെയ്യാൻ ഞങ്ങൾക്ക് നിങ്ങളുടെ സഹായം ആവശ്യമാണ്</b>
|
<b>ഈ README നിങ്ങളുടെ മാതൃഭാഷയിലേക്ക് വിവർത്തനം ചെയ്യാൻ ഞങ്ങൾക്ക് നിങ്ങളുടെ സഹായം ആവശ്യമാണ്</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
ഞങ്ങളുമായി ചാറ്റ് ചെയ്യുക: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
ഞങ്ങളുമായി ചാറ്റ് ചെയ്യുക: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structuur</a> •
|
<a href="#file-structure">Structuur</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>We hebben je hulp nodig om deze README te vertalen naar jouw moedertaal</b>
|
<b>We hebben je hulp nodig om deze README te vertalen naar jouw moedertaal</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Praat met ons: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Praat met ons: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#jak-kompilować-za-pomocą-dockera">Docker</a> •
|
<a href="#jak-kompilować-za-pomocą-dockera">Docker</a> •
|
||||||
<a href="#struktura-plików">Struktura</a> •
|
<a href="#struktura-plików">Struktura</a> •
|
||||||
<a href="#migawkisnapshoty">Snapshot</a><br>
|
<a href="#migawkisnapshoty">Snapshot</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Potrzebujemy twojej pomocy w tłumaczeniu README na twój ojczysty język</b>
|
<b>Potrzebujemy twojej pomocy w tłumaczeniu README na twój ojczysty język</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Porozmawiaj z nami na: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Porozmawiaj z nami na: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
<a href="#como-compilar-com-docker">Docker</a> •
|
<a href="#como-compilar-com-docker">Docker</a> •
|
||||||
<a href="#estrutura-de-arquivos">Estrutura</a> •
|
<a href="#estrutura-de-arquivos">Estrutura</a> •
|
||||||
<a href="#screenshots">Screenshots</a><br>
|
<a href="#screenshots">Screenshots</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Precisamos de sua ajuda para traduzir este README e a <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">UI do RustDesk</a> para sua língua nativa</b>
|
<b>Precisamos de sua ajuda para traduzir este README e a <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">UI do RustDesk</a> para sua língua nativa</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Converse conosco: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Converse conosco: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structure</a> •
|
<a href="#file-structure">Structure</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>Нам нужна ваша помощь для перевода этого README и <a href="https://github.com/rustdesk/rustdesk/tree/master/src/rustdesk/tree/master/src/lang">RustDesk UI</a> на ваш родной язык</B>
|
<b>Нам нужна ваша помощь для перевода этого README и <a href="https://github.com/rustdesk/rustdesk/tree/master/src/rustdesk/tree/master/src/lang">RustDesk UI</a> на ваш родной язык</B>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#使用Docker编译">Docker</a> •
|
<a href="#使用Docker编译">Docker</a> •
|
||||||
<a href="#文件结构">结构</a> •
|
<a href="#文件结构">结构</a> •
|
||||||
<a href="#截图">截图</a><br>
|
<a href="#截图">截图</a><br>
|
||||||
[<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Chat with us: [知乎](https://www.zhihu.com/people/rustdesk) | [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Chat with us: [知乎](https://www.zhihu.com/people/rustdesk) | [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="#how-to-build-with-docker">Docker</a> •
|
<a href="#how-to-build-with-docker">Docker</a> •
|
||||||
<a href="#file-structure">Structure</a> •
|
<a href="#file-structure">Structure</a> •
|
||||||
<a href="#snapshot">Snapshot</a><br>
|
<a href="#snapshot">Snapshot</a><br>
|
||||||
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
[<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>]<br>
|
||||||
<b>We need your help to translate this README, <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a> and <a href="https://github.com/rustdesk/doc.rustdesk.com">Doc</a> to your native language</b>
|
<b>We need your help to translate this README, <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk UI</a> and <a href="https://github.com/rustdesk/doc.rustdesk.com">Doc</a> to your native language</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package="com.carriez.flutter_hbb">
|
package="com.carriez.flutter_hbb">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
@ -8,14 +8,14 @@ package com.carriez.flutter_hbb
|
|||||||
|
|
||||||
import android.accessibilityservice.AccessibilityService
|
import android.accessibilityservice.AccessibilityService
|
||||||
import android.accessibilityservice.GestureDescription
|
import android.accessibilityservice.GestureDescription
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Path
|
import android.graphics.Path
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.accessibility.AccessibilityEvent
|
import android.view.accessibility.AccessibilityEvent
|
||||||
import androidx.annotation.Keep
|
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
const val LIFT_DOWN = 9
|
const val LIFT_DOWN = 9
|
||||||
const val LIFT_MOVE = 8
|
const val LIFT_MOVE = 8
|
||||||
@ -49,28 +49,40 @@ class InputService : AccessibilityService() {
|
|||||||
|
|
||||||
private val wheelActionsQueue = LinkedList<GestureDescription>()
|
private val wheelActionsQueue = LinkedList<GestureDescription>()
|
||||||
private var isWheelActionsPolling = false
|
private var isWheelActionsPolling = false
|
||||||
|
private var isWaitingLongPress = false
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.N)
|
@RequiresApi(Build.VERSION_CODES.N)
|
||||||
fun onMouseInput(mask: Int, _x: Int, _y: Int) {
|
fun onMouseInput(mask: Int, _x: Int, _y: Int) {
|
||||||
val x = if (_x < 0) {
|
val x = max(0, _x)
|
||||||
0
|
val y = max(0, _y)
|
||||||
} else {
|
|
||||||
_x
|
|
||||||
}
|
|
||||||
|
|
||||||
val y = if (_y < 0) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
_y
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask == 0 || mask == LIFT_MOVE) {
|
if (mask == 0 || mask == LIFT_MOVE) {
|
||||||
|
val oldX = mouseX
|
||||||
|
val oldY = mouseY
|
||||||
mouseX = x * SCREEN_INFO.scale
|
mouseX = x * SCREEN_INFO.scale
|
||||||
mouseY = y * SCREEN_INFO.scale
|
mouseY = y * SCREEN_INFO.scale
|
||||||
|
if (isWaitingLongPress) {
|
||||||
|
val delta = abs(oldX - mouseX) + abs(oldY - mouseY)
|
||||||
|
Log.d(logTag,"delta:$delta")
|
||||||
|
if (delta > 8) {
|
||||||
|
isWaitingLongPress = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// left button down ,was up
|
// left button down ,was up
|
||||||
if (mask == LIFT_DOWN) {
|
if (mask == LIFT_DOWN) {
|
||||||
|
isWaitingLongPress = true
|
||||||
|
timer.schedule(object : TimerTask() {
|
||||||
|
override fun run() {
|
||||||
|
if (isWaitingLongPress) {
|
||||||
|
isWaitingLongPress = false
|
||||||
|
leftIsDown = false
|
||||||
|
endGesture(mouseX, mouseY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, LONG_TAP_DELAY * 4)
|
||||||
|
|
||||||
leftIsDown = true
|
leftIsDown = true
|
||||||
startGesture(mouseX, mouseY)
|
startGesture(mouseX, mouseY)
|
||||||
return
|
return
|
||||||
@ -83,10 +95,13 @@ class InputService : AccessibilityService() {
|
|||||||
|
|
||||||
// left up ,was down
|
// left up ,was down
|
||||||
if (mask == LIFT_UP) {
|
if (mask == LIFT_UP) {
|
||||||
|
if (leftIsDown) {
|
||||||
leftIsDown = false
|
leftIsDown = false
|
||||||
|
isWaitingLongPress = false
|
||||||
endGesture(mouseX, mouseY)
|
endGesture(mouseX, mouseY)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mask == RIGHT_UP) {
|
if (mask == RIGHT_UP) {
|
||||||
performGlobalAction(GLOBAL_ACTION_BACK)
|
performGlobalAction(GLOBAL_ACTION_BACK)
|
||||||
|
@ -192,7 +192,6 @@ class MainActivity : FlutterActivity() {
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val inputPer = InputService.isOpen
|
val inputPer = InputService.isOpen
|
||||||
Log.d(logTag, "onResume inputPer:$inputPer")
|
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
flutterMethodChannel.invokeMethod(
|
flutterMethodChannel.invokeMethod(
|
||||||
"on_state_changed",
|
"on_state_changed",
|
||||||
|
@ -2,20 +2,26 @@ package com.carriez.flutter_hbb
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.media.AudioRecord
|
import android.media.AudioRecord
|
||||||
import android.media.AudioRecord.READ_BLOCKING
|
import android.media.AudioRecord.READ_BLOCKING
|
||||||
import android.media.MediaCodecList
|
import android.media.MediaCodecList
|
||||||
import android.media.MediaFormat
|
import android.media.MediaFormat
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.os.PowerManager
|
||||||
|
import android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
|
||||||
|
import android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.content.ContextCompat.getSystemService
|
||||||
import com.hjq.permissions.Permission
|
import com.hjq.permissions.Permission
|
||||||
import com.hjq.permissions.XXPermissions
|
import com.hjq.permissions.XXPermissions
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("ConstantLocale")
|
@SuppressLint("ConstantLocale")
|
||||||
val LOCAL_NAME = Locale.getDefault().toString()
|
val LOCAL_NAME = Locale.getDefault().toString()
|
||||||
val SCREEN_INFO = Info(0, 0, 1, 200)
|
val SCREEN_INFO = Info(0, 0, 1, 200)
|
||||||
@ -38,8 +44,31 @@ fun testVP9Support(): Boolean {
|
|||||||
return res != null
|
return res != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
fun requestPermission(context: Context, type: String) {
|
fun requestPermission(context: Context, type: String) {
|
||||||
val permission = when (type) {
|
val permission = when (type) {
|
||||||
|
"ignore_battery_optimizations" -> {
|
||||||
|
try {
|
||||||
|
context.startActivity(Intent(ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
|
||||||
|
data = Uri.parse("package:" + context.packageName)
|
||||||
|
})
|
||||||
|
} catch (e:Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
"application_details_settings" -> {
|
||||||
|
try {
|
||||||
|
context.startActivity(Intent().apply {
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
action = "android.settings.APPLICATION_DETAILS_SETTINGS"
|
||||||
|
data = Uri.parse("package:" + context.packageName)
|
||||||
|
})
|
||||||
|
} catch (e:Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
"audio" -> {
|
"audio" -> {
|
||||||
Permission.RECORD_AUDIO
|
Permission.RECORD_AUDIO
|
||||||
}
|
}
|
||||||
@ -52,7 +81,7 @@ fun requestPermission(context: Context, type: String) {
|
|||||||
}
|
}
|
||||||
XXPermissions.with(context)
|
XXPermissions.with(context)
|
||||||
.permission(permission)
|
.permission(permission)
|
||||||
.request { permissions, all ->
|
.request { _, all ->
|
||||||
if (all) {
|
if (all) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
MainActivity.flutterMethodChannel.invokeMethod(
|
MainActivity.flutterMethodChannel.invokeMethod(
|
||||||
@ -64,8 +93,13 @@ fun requestPermission(context: Context, type: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
fun checkPermission(context: Context, type: String): Boolean {
|
fun checkPermission(context: Context, type: String): Boolean {
|
||||||
val permission = when (type) {
|
val permission = when (type) {
|
||||||
|
"ignore_battery_optimizations" -> {
|
||||||
|
val pw = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||||
|
return pw.isIgnoringBatteryOptimizations(context.packageName)
|
||||||
|
}
|
||||||
"audio" -> {
|
"audio" -> {
|
||||||
Permission.RECORD_AUDIO
|
Permission.RECORD_AUDIO
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,12 @@ class PermissionManager {
|
|||||||
static Timer? _timer;
|
static Timer? _timer;
|
||||||
static var _current = "";
|
static var _current = "";
|
||||||
|
|
||||||
static final permissions = ["audio", "file"];
|
static final permissions = [
|
||||||
|
"audio",
|
||||||
|
"file",
|
||||||
|
"ignore_battery_optimizations",
|
||||||
|
"application_details_settings"
|
||||||
|
];
|
||||||
|
|
||||||
static bool isWaitingFile() {
|
static bool isWaitingFile() {
|
||||||
if (_completer != null) {
|
if (_completer != null) {
|
||||||
@ -279,9 +284,12 @@ class PermissionManager {
|
|||||||
if (!permissions.contains(type))
|
if (!permissions.contains(type))
|
||||||
return Future.error("Wrong permission!$type");
|
return Future.error("Wrong permission!$type");
|
||||||
|
|
||||||
|
FFI.invokeMethod("request_permission", type);
|
||||||
|
if (type == "ignore_battery_optimizations") {
|
||||||
|
return Future.value(false);
|
||||||
|
}
|
||||||
_current = type;
|
_current = type;
|
||||||
_completer = Completer<bool>();
|
_completer = Completer<bool>();
|
||||||
FFI.invokeMethod("request_permission", type);
|
|
||||||
|
|
||||||
// timeout
|
// timeout
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
|
@ -262,7 +262,6 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
: SafeArea(child:
|
: SafeArea(child:
|
||||||
OrientationBuilder(builder: (ctx, orientation) {
|
OrientationBuilder(builder: (ctx, orientation) {
|
||||||
if (_currentOrientation != orientation) {
|
if (_currentOrientation != orientation) {
|
||||||
debugPrint("on orientation changed");
|
|
||||||
Timer(Duration(milliseconds: 200), () {
|
Timer(Duration(milliseconds: 200), () {
|
||||||
resetMobileActionsOverlay();
|
resetMobileActionsOverlay();
|
||||||
_currentOrientation = orientation;
|
_currentOrientation = orientation;
|
||||||
@ -1061,6 +1060,8 @@ void showOptions() {
|
|||||||
getRadio('Optimize reaction time', 'low', quality, setQuality),
|
getRadio('Optimize reaction time', 'low', quality, setQuality),
|
||||||
Divider(color: MyTheme.border),
|
Divider(color: MyTheme.border),
|
||||||
getToggle(setState, 'show-remote-cursor', 'Show remote cursor'),
|
getToggle(setState, 'show-remote-cursor', 'Show remote cursor'),
|
||||||
|
getToggle(
|
||||||
|
setState, 'show-quality-monitor', 'Show quality monitor'),
|
||||||
] +
|
] +
|
||||||
more),
|
more),
|
||||||
actions: [],
|
actions: [],
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:settings_ui/settings_ui.dart';
|
import 'package:settings_ui/settings_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
@ -24,13 +26,100 @@ class SettingsPage extends StatefulWidget implements PageShape {
|
|||||||
_SettingsState createState() => _SettingsState();
|
_SettingsState createState() => _SettingsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SettingsState extends State<SettingsPage> {
|
class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||||
static const url = 'https://rustdesk.com/';
|
static const url = 'https://rustdesk.com/';
|
||||||
|
final _hasIgnoreBattery = androidVersion >= 26;
|
||||||
|
var _ignoreBatteryOpt = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
if (_hasIgnoreBattery) {
|
||||||
|
updateIgnoreBatteryStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
|
if (state == AppLifecycleState.resumed) {
|
||||||
|
updateIgnoreBatteryStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> updateIgnoreBatteryStatus() async {
|
||||||
|
final res = await PermissionManager.check("ignore_battery_optimizations");
|
||||||
|
if (_ignoreBatteryOpt != res) {
|
||||||
|
setState(() {
|
||||||
|
_ignoreBatteryOpt = res;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Provider.of<FfiModel>(context);
|
Provider.of<FfiModel>(context);
|
||||||
final username = getUsername();
|
final username = getUsername();
|
||||||
|
final enableAbr = FFI.getByName("option", "enable-abr") != 'N';
|
||||||
|
final enhancementsTiles = [
|
||||||
|
SettingsTile.switchTile(
|
||||||
|
title: Text(translate('Adaptive Bitrate') + '(beta)'),
|
||||||
|
initialValue: enableAbr,
|
||||||
|
onToggle: (v) {
|
||||||
|
final msg = Map()
|
||||||
|
..["name"] = "enable-abr"
|
||||||
|
..["value"] = "";
|
||||||
|
if (!v) {
|
||||||
|
msg["value"] = "N";
|
||||||
|
}
|
||||||
|
FFI.setByName("option", json.encode(msg));
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
)
|
||||||
|
];
|
||||||
|
if (_hasIgnoreBattery) {
|
||||||
|
enhancementsTiles.insert(
|
||||||
|
0,
|
||||||
|
SettingsTile.switchTile(
|
||||||
|
initialValue: _ignoreBatteryOpt,
|
||||||
|
title: Text(translate('Keep RustDesk background service')),
|
||||||
|
description:
|
||||||
|
Text('* ${translate('Ignore Battery Optimizations')}'),
|
||||||
|
onToggle: (v) async {
|
||||||
|
if (v) {
|
||||||
|
PermissionManager.request("ignore_battery_optimizations");
|
||||||
|
} else {
|
||||||
|
final res = await DialogManager.show<bool>(
|
||||||
|
(setState, close) => CustomAlertDialog(
|
||||||
|
title: Text(translate("Open System Setting")),
|
||||||
|
content: Text(translate(
|
||||||
|
"android_open_battery_optimizations_tip")),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => close(),
|
||||||
|
child: Text(translate("Cancel"))),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => close(true),
|
||||||
|
child:
|
||||||
|
Text(translate("Open System Setting"))),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
if (res == true) {
|
||||||
|
PermissionManager.request("application_details_settings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
return SettingsList(
|
return SettingsList(
|
||||||
sections: [
|
sections: [
|
||||||
SettingsSection(
|
SettingsSection(
|
||||||
@ -51,17 +140,17 @@ class _SettingsState extends State<SettingsPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SettingsSection(
|
SettingsSection(title: Text(translate("Settings")), tiles: [
|
||||||
title: Text(translate("Settings")),
|
|
||||||
tiles: [
|
|
||||||
SettingsTile.navigation(
|
SettingsTile.navigation(
|
||||||
title: Text(translate('ID/Relay Server')),
|
title: Text(translate('ID/Relay Server')),
|
||||||
leading: Icon(Icons.cloud),
|
leading: Icon(Icons.cloud),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
showServerSettings();
|
showServerSettings();
|
||||||
},
|
})
|
||||||
),
|
]),
|
||||||
],
|
SettingsSection(
|
||||||
|
title: Text(translate("Enhancements")),
|
||||||
|
tiles: enhancementsTiles,
|
||||||
),
|
),
|
||||||
SettingsSection(
|
SettingsSection(
|
||||||
title: Text(translate("About")),
|
title: Text(translate("About")),
|
||||||
|
@ -7,9 +7,9 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
protobuf = { version = "3.1.0", features = ["with-bytes"] }
|
protobuf = { version = "3.1", features = ["with-bytes"] }
|
||||||
tokio = { version = "1.15", features = ["full"] }
|
tokio = { version = "1.20", features = ["full"] }
|
||||||
tokio-util = { version = "0.6", features = ["full"] }
|
tokio-util = { version = "0.7", features = ["full"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
bytes = "1.1"
|
bytes = "1.1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
@ -23,6 +23,7 @@ directories-next = "2.0"
|
|||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
|
serde_with = "1.14.0"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
confy = { git = "https://github.com/open-trade/confy" }
|
confy = { git = "https://github.com/open-trade/confy" }
|
||||||
dirs-next = "2.0"
|
dirs-next = "2.0"
|
||||||
@ -38,7 +39,7 @@ mac_address = "1.1"
|
|||||||
quic = []
|
quic = []
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
protobuf-codegen = { version = "3.1.0" }
|
protobuf-codegen = { version = "3.1" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["winuser"] }
|
winapi = { version = "0.3", features = ["winuser"] }
|
||||||
|
@ -856,10 +856,26 @@ impl LocalConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct DiscoveryPeer {
|
||||||
|
pub id: String,
|
||||||
|
#[serde(with = "serde_with::rust::map_as_tuple_list")]
|
||||||
|
pub ip_mac: HashMap<String, String>,
|
||||||
|
pub username: String,
|
||||||
|
pub hostname: String,
|
||||||
|
pub platform: String,
|
||||||
|
pub online: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiscoveryPeer {
|
||||||
|
pub fn is_same_peer(&self, other: &DiscoveryPeer) -> bool {
|
||||||
|
self.id == other.id && self.username == other.username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
pub struct LanPeers {
|
pub struct LanPeers {
|
||||||
#[serde(default)]
|
pub peers: Vec<DiscoveryPeer>,
|
||||||
pub peers: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LanPeers {
|
impl LanPeers {
|
||||||
@ -874,8 +890,10 @@ impl LanPeers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store(peers: String) {
|
pub fn store(peers: &Vec<DiscoveryPeer>) {
|
||||||
let f = LanPeers { peers };
|
let f = LanPeers {
|
||||||
|
peers: peers.clone(),
|
||||||
|
};
|
||||||
if let Err(err) = confy::store_path(Config::file_("_lan_peers"), f) {
|
if let Err(err) = confy::store_path(Config::file_("_lan_peers"), f) {
|
||||||
log::error!("Failed to store lan peers: {}", err);
|
log::error!("Failed to store lan peers: {}", err);
|
||||||
}
|
}
|
||||||
|
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "1.62.0"
|
@ -148,11 +148,25 @@ impl Client {
|
|||||||
true,
|
true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let rendezvous_server = crate::get_rendezvous_server(1_000).await;
|
let (mut rendezvous_server, servers, contained) = crate::get_rendezvous_server(1_000).await;
|
||||||
log::info!("rendezvous server: {}", rendezvous_server);
|
|
||||||
|
|
||||||
let mut socket =
|
let mut socket =
|
||||||
socket_client::connect_tcp(&*rendezvous_server, any_addr, RENDEZVOUS_TIMEOUT).await?;
|
socket_client::connect_tcp(&*rendezvous_server, any_addr, RENDEZVOUS_TIMEOUT).await;
|
||||||
|
debug_assert!(!servers.contains(&rendezvous_server));
|
||||||
|
if socket.is_err() && !servers.is_empty() {
|
||||||
|
log::info!("try the other servers: {:?}", servers);
|
||||||
|
for server in servers {
|
||||||
|
socket = socket_client::connect_tcp(&*server, any_addr, RENDEZVOUS_TIMEOUT).await;
|
||||||
|
if socket.is_ok() {
|
||||||
|
rendezvous_server = server;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crate::refresh_rendezvous_server();
|
||||||
|
} else if !contained {
|
||||||
|
crate::refresh_rendezvous_server();
|
||||||
|
}
|
||||||
|
log::info!("rendezvous server: {}", rendezvous_server);
|
||||||
|
let mut socket = socket?;
|
||||||
let my_addr = socket.local_addr();
|
let my_addr = socket.local_addr();
|
||||||
let mut signed_id_pk = Vec::new();
|
let mut signed_id_pk = Vec::new();
|
||||||
let mut relay_server = "".to_owned();
|
let mut relay_server = "".to_owned();
|
||||||
|
@ -12,7 +12,6 @@ use hbb_common::{
|
|||||||
rendezvous_proto::*,
|
rendezvous_proto::*,
|
||||||
sleep, socket_client, tokio, ResultType,
|
sleep, socket_client, tokio, ResultType,
|
||||||
};
|
};
|
||||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
|
|
||||||
use hbb_common::{config::RENDEZVOUS_PORT, futures::future::join_all};
|
use hbb_common::{config::RENDEZVOUS_PORT, futures::future::join_all};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
@ -247,7 +246,7 @@ async fn test_nat_type_() -> ResultType<bool> {
|
|||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
let rendezvous_server = get_rendezvous_server(1_000).await;
|
let (rendezvous_server, _, _) = get_rendezvous_server(1_000).await;
|
||||||
let server1 = rendezvous_server;
|
let server1 = rendezvous_server;
|
||||||
let tmp: Vec<&str> = server1.split(":").collect();
|
let tmp: Vec<&str> = server1.split(":").collect();
|
||||||
if tmp.len() != 2 {
|
if tmp.len() != 2 {
|
||||||
@ -316,31 +315,62 @@ async fn test_nat_type_() -> ResultType<bool> {
|
|||||||
Ok(ok)
|
Ok(ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_rendezvous_server(ms_timeout: u64) -> (String, Vec<String>, bool) {
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
pub async fn get_rendezvous_server(_ms_timeout: u64) -> String {
|
let (mut a, mut b) = get_rendezvous_server_(ms_timeout);
|
||||||
Config::get_rendezvous_server()
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
let (mut a, mut b) = get_rendezvous_server_(ms_timeout).await;
|
||||||
|
let mut b: Vec<String> = b
|
||||||
|
.drain(..)
|
||||||
|
.map(|x| {
|
||||||
|
if !x.contains(":") {
|
||||||
|
format!("{}:{}", x, config::RENDEZVOUS_PORT)
|
||||||
|
} else {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let c = if b.contains(&a) {
|
||||||
|
b = b.drain(..).filter(|x| x != &a).collect();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
a = b.pop().unwrap_or(a);
|
||||||
|
false
|
||||||
|
};
|
||||||
|
(a, b, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
fn get_rendezvous_server_(_ms_timeout: u64) -> (String, Vec<String>) {
|
||||||
|
(
|
||||||
|
Config::get_rendezvous_server(),
|
||||||
|
Config::get_rendezvous_servers(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub async fn get_rendezvous_server(ms_timeout: u64) -> String {
|
async fn get_rendezvous_server_(ms_timeout: u64) -> (String, Vec<String>) {
|
||||||
crate::ipc::get_rendezvous_server(ms_timeout).await
|
crate::ipc::get_rendezvous_server(ms_timeout).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
pub async fn get_nat_type(_ms_timeout: u64) -> i32 {
|
pub async fn get_nat_type(_ms_timeout: u64) -> i32 {
|
||||||
Config::get_nat_type()
|
Config::get_nat_type()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub async fn get_nat_type(ms_timeout: u64) -> i32 {
|
pub async fn get_nat_type(ms_timeout: u64) -> i32 {
|
||||||
crate::ipc::get_nat_type(ms_timeout).await
|
crate::ipc::get_nat_type(ms_timeout).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn test_rendezvous_server_() {
|
async fn test_rendezvous_server_() {
|
||||||
let servers = Config::get_rendezvous_servers();
|
let servers = Config::get_rendezvous_servers();
|
||||||
hbb_common::config::ONLINE.lock().unwrap().clear();
|
Config::reset_online();
|
||||||
let mut futs = Vec::new();
|
let mut futs = Vec::new();
|
||||||
for host in servers {
|
for host in servers {
|
||||||
futs.push(tokio::spawn(async move {
|
futs.push(tokio::spawn(async move {
|
||||||
@ -363,11 +393,21 @@ async fn test_rendezvous_server_() {
|
|||||||
join_all(futs).await;
|
join_all(futs).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
|
|
||||||
pub fn test_rendezvous_server() {
|
pub fn test_rendezvous_server() {
|
||||||
std::thread::spawn(test_rendezvous_server_);
|
std::thread::spawn(test_rendezvous_server_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refresh_rendezvous_server() {
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
|
||||||
|
test_rendezvous_server();
|
||||||
|
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
|
||||||
|
std::thread::spawn(|| {
|
||||||
|
if crate::ipc::test_rendezvous_server().is_err() {
|
||||||
|
test_rendezvous_server();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_time() -> i64 {
|
pub fn get_time() -> i64 {
|
||||||
std::time::SystemTime::now()
|
std::time::SystemTime::now()
|
||||||
@ -437,14 +477,15 @@ pub fn is_modifier(evt: &KeyEvent) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_software_update() {
|
pub fn check_software_update() {
|
||||||
std::thread::spawn(move || allow_err!(_check_software_update()));
|
std::thread::spawn(move || allow_err!(check_software_update_()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn _check_software_update() -> hbb_common::ResultType<()> {
|
async fn check_software_update_() -> hbb_common::ResultType<()> {
|
||||||
sleep(3.).await;
|
sleep(3.).await;
|
||||||
|
|
||||||
let rendezvous_server = socket_client::get_target_addr(&get_rendezvous_server(1_000).await)?;
|
let rendezvous_server =
|
||||||
|
socket_client::get_target_addr(&format!("rs-sg.rustdesk.com:{}", config::RENDEZVOUS_PORT))?;
|
||||||
let mut socket =
|
let mut socket =
|
||||||
socket_client::new_udp(Config::get_any_listen_addr(), RENDEZVOUS_TIMEOUT).await?;
|
socket_client::new_udp(Config::get_any_listen_addr(), RENDEZVOUS_TIMEOUT).await?;
|
||||||
|
|
||||||
|
30
src/ipc.rs
30
src/ipc.rs
@ -127,6 +127,7 @@ pub enum Data {
|
|||||||
ClipbaordFile(ClipbaordFile),
|
ClipbaordFile(ClipbaordFile),
|
||||||
ClipboardFileEnabled(bool),
|
ClipboardFileEnabled(bool),
|
||||||
PrivacyModeState((i32, PrivacyModeState)),
|
PrivacyModeState((i32, PrivacyModeState)),
|
||||||
|
TestRendezvousServer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
@ -286,7 +287,11 @@ async fn handle(data: Data, stream: &mut Connection) {
|
|||||||
} else if name == "salt" {
|
} else if name == "salt" {
|
||||||
value = Some(Config::get_salt());
|
value = Some(Config::get_salt());
|
||||||
} else if name == "rendezvous_server" {
|
} else if name == "rendezvous_server" {
|
||||||
value = Some(Config::get_rendezvous_server());
|
value = Some(format!(
|
||||||
|
"{},{}",
|
||||||
|
Config::get_rendezvous_server(),
|
||||||
|
Config::get_rendezvous_servers().join(",")
|
||||||
|
));
|
||||||
} else if name == "rendezvous_servers" {
|
} else if name == "rendezvous_servers" {
|
||||||
value = Some(Config::get_rendezvous_servers().join(","));
|
value = Some(Config::get_rendezvous_servers().join(","));
|
||||||
} else {
|
} else {
|
||||||
@ -336,7 +341,9 @@ async fn handle(data: Data, stream: &mut Connection) {
|
|||||||
.await
|
.await
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Data::TestRendezvousServer => {
|
||||||
|
crate::test_rendezvous_server();
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -520,11 +527,17 @@ pub fn get_password() -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_rendezvous_server(ms_timeout: u64) -> String {
|
pub async fn get_rendezvous_server(ms_timeout: u64) -> (String, Vec<String>) {
|
||||||
if let Ok(Some(v)) = get_config_async("rendezvous_server", ms_timeout).await {
|
if let Ok(Some(v)) = get_config_async("rendezvous_server", ms_timeout).await {
|
||||||
v
|
let mut urls = v.split(",");
|
||||||
|
let a = urls.next().unwrap_or_default().to_owned();
|
||||||
|
let b: Vec<String> = urls.map(|x| x.to_owned()).collect();
|
||||||
|
(a, b)
|
||||||
} else {
|
} else {
|
||||||
Config::get_rendezvous_server()
|
(
|
||||||
|
Config::get_rendezvous_server(),
|
||||||
|
Config::get_rendezvous_servers(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,3 +649,10 @@ pub async fn set_socks(value: config::Socks5Server) -> ResultType<()> {
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
pub async fn test_rendezvous_server() -> ResultType<()> {
|
||||||
|
let mut c = connect(1000, "").await?;
|
||||||
|
c.send(&Data::TestRendezvousServer).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
291
src/lan.rs
Normal file
291
src/lan.rs
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
use hbb_common::{
|
||||||
|
allow_err,
|
||||||
|
anyhow::bail,
|
||||||
|
config::{self, Config, RENDEZVOUS_PORT},
|
||||||
|
log,
|
||||||
|
protobuf::Message as _,
|
||||||
|
rendezvous_proto::*,
|
||||||
|
tokio::{
|
||||||
|
self,
|
||||||
|
sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||||
|
},
|
||||||
|
ResultType,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
net::{IpAddr, Ipv4Addr, SocketAddr, ToSocketAddrs, UdpSocket},
|
||||||
|
time::Instant,
|
||||||
|
};
|
||||||
|
|
||||||
|
type Message = RendezvousMessage;
|
||||||
|
|
||||||
|
pub(super) fn start_listening() -> ResultType<()> {
|
||||||
|
let addr = SocketAddr::from(([0, 0, 0, 0], get_broadcast_port()));
|
||||||
|
let socket = std::net::UdpSocket::bind(addr)?;
|
||||||
|
socket.set_read_timeout(Some(std::time::Duration::from_millis(1000)))?;
|
||||||
|
log::info!("lan discovery listener started");
|
||||||
|
loop {
|
||||||
|
let mut buf = [0; 2048];
|
||||||
|
if let Ok((len, addr)) = socket.recv_from(&mut buf) {
|
||||||
|
if let Ok(msg_in) = Message::parse_from_bytes(&buf[0..len]) {
|
||||||
|
match msg_in.union {
|
||||||
|
Some(rendezvous_message::Union::PeerDiscovery(p)) => {
|
||||||
|
if p.cmd == "ping" {
|
||||||
|
if let Some(self_addr) = get_ipaddr_by_peer(&addr) {
|
||||||
|
let mut msg_out = Message::new();
|
||||||
|
let peer = PeerDiscovery {
|
||||||
|
cmd: "pong".to_owned(),
|
||||||
|
mac: get_mac(&self_addr),
|
||||||
|
id: Config::get_id(),
|
||||||
|
hostname: whoami::hostname(),
|
||||||
|
username: crate::platform::get_active_username(),
|
||||||
|
platform: whoami::platform().to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
msg_out.set_peer_discovery(peer);
|
||||||
|
socket.send_to(&msg_out.write_to_bytes()?, addr).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
pub async fn discover() -> ResultType<()> {
|
||||||
|
let sockets = send_query()?;
|
||||||
|
let rx = spawn_wait_responses(sockets);
|
||||||
|
handle_received_peers(rx).await?;
|
||||||
|
|
||||||
|
log::info!("discover ping done");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_wol(id: String) {
|
||||||
|
let interfaces = default_net::get_interfaces();
|
||||||
|
for peer in &config::LanPeers::load().peers {
|
||||||
|
if peer.id == id {
|
||||||
|
for (ip, mac) in peer.ip_mac.iter() {
|
||||||
|
if let Ok(mac_addr) = mac.parse() {
|
||||||
|
if let Ok(IpAddr::V4(ip)) = ip.parse() {
|
||||||
|
for interface in &interfaces {
|
||||||
|
for ipv4 in &interface.ipv4 {
|
||||||
|
if (u32::from(ipv4.addr) & u32::from(ipv4.netmask))
|
||||||
|
== (u32::from(ip) & u32::from(ipv4.netmask))
|
||||||
|
{
|
||||||
|
allow_err!(wol::send_wol(
|
||||||
|
mac_addr,
|
||||||
|
None,
|
||||||
|
Some(IpAddr::V4(ipv4.addr))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_broadcast_port() -> u16 {
|
||||||
|
(RENDEZVOUS_PORT + 3) as _
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mac(ip: &IpAddr) -> String {
|
||||||
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
if let Ok(mac) = get_mac_by_ip(ip) {
|
||||||
|
mac.to_string()
|
||||||
|
} else {
|
||||||
|
"".to_owned()
|
||||||
|
}
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
"".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_all_ipv4s() -> ResultType<Vec<Ipv4Addr>> {
|
||||||
|
let mut ipv4s = Vec::new();
|
||||||
|
for interface in default_net::get_interfaces() {
|
||||||
|
for ipv4 in &interface.ipv4 {
|
||||||
|
ipv4s.push(ipv4.addr.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(ipv4s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mac_by_ip(ip: &IpAddr) -> ResultType<String> {
|
||||||
|
for interface in default_net::get_interfaces() {
|
||||||
|
match ip {
|
||||||
|
IpAddr::V4(local_ipv4) => {
|
||||||
|
if interface.ipv4.iter().any(|x| x.addr == *local_ipv4) {
|
||||||
|
if let Some(mac_addr) = interface.mac_addr {
|
||||||
|
return Ok(mac_addr.address());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IpAddr::V6(local_ipv6) => {
|
||||||
|
if interface.ipv6.iter().any(|x| x.addr == *local_ipv6) {
|
||||||
|
if let Some(mac_addr) = interface.mac_addr {
|
||||||
|
return Ok(mac_addr.address());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bail!("No interface found for ip: {:?}", ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mainly from https://github.com/shellrow/default-net/blob/cf7ca24e7e6e8e566ed32346c9cfddab3f47e2d6/src/interface/shared.rs#L4
|
||||||
|
fn get_ipaddr_by_peer<A: ToSocketAddrs>(peer: A) -> Option<IpAddr> {
|
||||||
|
let socket = match UdpSocket::bind("0.0.0.0:0") {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
match socket.connect(peer) {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
match socket.local_addr() {
|
||||||
|
Ok(addr) => return Some(addr.ip()),
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_broadcast_sockets() -> ResultType<Vec<UdpSocket>> {
|
||||||
|
let mut sockets = Vec::new();
|
||||||
|
for v4_addr in get_all_ipv4s()? {
|
||||||
|
if v4_addr.is_private() {
|
||||||
|
let s = UdpSocket::bind(SocketAddr::from((v4_addr, 0)))?;
|
||||||
|
s.set_broadcast(true)?;
|
||||||
|
log::debug!("Bind socket to {}", &v4_addr);
|
||||||
|
sockets.push(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(sockets)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_query() -> ResultType<Vec<UdpSocket>> {
|
||||||
|
let sockets = create_broadcast_sockets()?;
|
||||||
|
if sockets.is_empty() {
|
||||||
|
bail!("Found no ipv4 addresses");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut msg_out = Message::new();
|
||||||
|
let peer = PeerDiscovery {
|
||||||
|
cmd: "ping".to_owned(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
msg_out.set_peer_discovery(peer);
|
||||||
|
let maddr = SocketAddr::from(([255, 255, 255, 255], get_broadcast_port()));
|
||||||
|
for socket in &sockets {
|
||||||
|
socket.send_to(&msg_out.write_to_bytes()?, maddr)?;
|
||||||
|
}
|
||||||
|
log::info!("discover ping sent");
|
||||||
|
Ok(sockets)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_response(
|
||||||
|
socket: UdpSocket,
|
||||||
|
timeout: Option<std::time::Duration>,
|
||||||
|
tx: UnboundedSender<config::DiscoveryPeer>,
|
||||||
|
) -> ResultType<()> {
|
||||||
|
let mut last_recv_time = Instant::now();
|
||||||
|
|
||||||
|
socket.set_read_timeout(timeout)?;
|
||||||
|
loop {
|
||||||
|
let mut buf = [0; 2048];
|
||||||
|
if let Ok((len, addr)) = socket.recv_from(&mut buf) {
|
||||||
|
if let Ok(msg_in) = Message::parse_from_bytes(&buf[0..len]) {
|
||||||
|
match msg_in.union {
|
||||||
|
Some(rendezvous_message::Union::PeerDiscovery(p)) => {
|
||||||
|
last_recv_time = Instant::now();
|
||||||
|
if p.cmd == "pong" {
|
||||||
|
let mac = if let Some(self_addr) = get_ipaddr_by_peer(&addr) {
|
||||||
|
get_mac(&self_addr)
|
||||||
|
} else {
|
||||||
|
"".to_owned()
|
||||||
|
};
|
||||||
|
|
||||||
|
if mac != p.mac {
|
||||||
|
allow_err!(tx.send(config::DiscoveryPeer {
|
||||||
|
id: p.id.clone(),
|
||||||
|
ip_mac: HashMap::from([
|
||||||
|
(addr.ip().to_string(), p.mac.clone(),)
|
||||||
|
]),
|
||||||
|
username: p.username.clone(),
|
||||||
|
hostname: p.hostname.clone(),
|
||||||
|
platform: p.platform.clone(),
|
||||||
|
online: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if last_recv_time.elapsed().as_millis() > 3_000 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_wait_responses(sockets: Vec<UdpSocket>) -> UnboundedReceiver<config::DiscoveryPeer> {
|
||||||
|
let (tx, rx) = unbounded_channel::<_>();
|
||||||
|
for socket in sockets {
|
||||||
|
let tx_clone = tx.clone();
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
allow_err!(wait_response(
|
||||||
|
socket,
|
||||||
|
Some(std::time::Duration::from_millis(10)),
|
||||||
|
tx_clone
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
rx
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_received_peers(mut rx: UnboundedReceiver<config::DiscoveryPeer>) -> ResultType<()> {
|
||||||
|
let mut peers = config::LanPeers::load().peers;
|
||||||
|
peers.iter_mut().for_each(|peer| {
|
||||||
|
peer.online = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut response_set = HashSet::new();
|
||||||
|
let mut last_write_time = Instant::now() - std::time::Duration::from_secs(4);
|
||||||
|
loop {
|
||||||
|
tokio::select! {
|
||||||
|
data = rx.recv() => match data {
|
||||||
|
Some(mut peer) => {
|
||||||
|
let in_response_set = !response_set.insert(peer.id.clone());
|
||||||
|
if let Some(pos) = peers.iter().position(|x| x.is_same_peer(&peer) ) {
|
||||||
|
let peer1 = peers.remove(pos);
|
||||||
|
if in_response_set {
|
||||||
|
peer.ip_mac.extend(peer1.ip_mac);
|
||||||
|
peer.online = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
peers.insert(0, peer);
|
||||||
|
if last_write_time.elapsed().as_millis() > 300 {
|
||||||
|
config::LanPeers::store(&peers);
|
||||||
|
last_write_time = Instant::now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config::LanPeers::store(&peers);
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -8,6 +8,7 @@ mod de;
|
|||||||
mod en;
|
mod en;
|
||||||
mod eo;
|
mod eo;
|
||||||
mod es;
|
mod es;
|
||||||
|
mod hu;
|
||||||
mod fr;
|
mod fr;
|
||||||
mod id;
|
mod id;
|
||||||
mod it;
|
mod it;
|
||||||
@ -28,6 +29,7 @@ lazy_static::lazy_static! {
|
|||||||
("tw", "繁體中文"),
|
("tw", "繁體中文"),
|
||||||
("pt", "Português"),
|
("pt", "Português"),
|
||||||
("es", "Español"),
|
("es", "Español"),
|
||||||
|
("hu", "Magyar"),
|
||||||
("ru", "Русский"),
|
("ru", "Русский"),
|
||||||
("sk", "Slovenčina"),
|
("sk", "Slovenčina"),
|
||||||
("id", "Indonesia"),
|
("id", "Indonesia"),
|
||||||
@ -68,6 +70,7 @@ pub fn translate_locale(name: String, locale: &str) -> String {
|
|||||||
"tw" => tw::T.deref(),
|
"tw" => tw::T.deref(),
|
||||||
"de" => de::T.deref(),
|
"de" => de::T.deref(),
|
||||||
"es" => es::T.deref(),
|
"es" => es::T.deref(),
|
||||||
|
"hu" => hu::T.deref(),
|
||||||
"ru" => ru::T.deref(),
|
"ru" => ru::T.deref(),
|
||||||
"eo" => eo::T.deref(),
|
"eo" => eo::T.deref(),
|
||||||
"id" => id::T.deref(),
|
"id" => id::T.deref(),
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "进入隐私模式"),
|
("In privacy mode", "进入隐私模式"),
|
||||||
("Out privacy mode", "退出隐私模式"),
|
("Out privacy mode", "退出隐私模式"),
|
||||||
("Language", "语言"),
|
("Language", "语言"),
|
||||||
|
("Keep RustDesk background service", "保持RustDesk后台服务"),
|
||||||
|
("Ignore Battery Optimizations", "忽略电池优化"),
|
||||||
|
("android_open_battery_optimizations_tip", "如需关闭此功能,请在接下来的RustDesk应用设置页面中,找到并进入 [电源] 页面,取消勾选 [不受限制]"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "v režimu soukromí"),
|
("In privacy mode", "v režimu soukromí"),
|
||||||
("Out privacy mode", "mimo režim soukromí"),
|
("Out privacy mode", "mimo režim soukromí"),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "I databeskyttelsestilstand"),
|
("In privacy mode", "I databeskyttelsestilstand"),
|
||||||
("Out privacy mode", "Databeskyttelsestilstand fra"),
|
("Out privacy mode", "Databeskyttelsestilstand fra"),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "im Datenschutzmodus"),
|
("In privacy mode", "im Datenschutzmodus"),
|
||||||
("Out privacy mode", "Datenschutzmodus aus"),
|
("Out privacy mode", "Datenschutzmodus aus"),
|
||||||
("Language", "Sprache"),
|
("Language", "Sprache"),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"),
|
("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"),
|
||||||
("doc_fix_wayland", "https://rustdesk.com/docs/en/manual/linux/#x11-required"),
|
("doc_fix_wayland", "https://rustdesk.com/docs/en/manual/linux/#x11-required"),
|
||||||
("server_not_support", "Not yet supported by the server"),
|
("server_not_support", "Not yet supported by the server"),
|
||||||
|
("android_open_battery_optimizations_tip", "If you want to disable this feature, please go to the next RustDesk application settings page, find and enter [Battery] ,Uncheck [Unrestricted]"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", ""),
|
("In privacy mode", ""),
|
||||||
("Out privacy mode", ""),
|
("Out privacy mode", ""),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "En modo de privacidad"),
|
("In privacy mode", "En modo de privacidad"),
|
||||||
("Out privacy mode", "Fuera del modo de privacidad"),
|
("Out privacy mode", "Fuera del modo de privacidad"),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "en mode privé"),
|
("In privacy mode", "en mode privé"),
|
||||||
("Out privacy mode", "hors mode de confidentialité"),
|
("Out privacy mode", "hors mode de confidentialité"),
|
||||||
("Language", "Langue"),
|
("Language", "Langue"),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
291
src/lang/hu.rs
Normal file
291
src/lang/hu.rs
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
lazy_static::lazy_static! {
|
||||||
|
pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||||
|
[
|
||||||
|
("Status", "Státusz"),
|
||||||
|
("Your Desktop", "A te asztalod"),
|
||||||
|
("desk_tip", "Az asztalod ezzel az ID-vel, és jelszóval érhető el."),
|
||||||
|
("Password", "Jelszó"),
|
||||||
|
("Ready", "Kész"),
|
||||||
|
("Established", "Létrejött"),
|
||||||
|
("connecting_status", "Kapcsolódás a RustDesk hálózatához..."),
|
||||||
|
("Enable Service", "A szolgáltatás bekapcsolása"),
|
||||||
|
("Start Service", "Szolgáltatás Elindítása"),
|
||||||
|
("Service is running", "A szolgáltatás fut"),
|
||||||
|
("Service is not running", "A szolgáltatás nem fut"),
|
||||||
|
("not_ready_status", "A RustDesk nem áll készen. Kérlek nézd meg a hálózati beállításaidat."),
|
||||||
|
("Control Remote Desktop", "Távoli Asztal Kontrollálása"),
|
||||||
|
("Transfer File", "Fájl Transzfer"),
|
||||||
|
("Connect", "Kapcsolódás"),
|
||||||
|
("Recent Sessions", "Korábbi Sessionök"),
|
||||||
|
("Address Book", "Címköny"),
|
||||||
|
("Confirmation", "Megerősít"),
|
||||||
|
("TCP Tunneling", "TCP Tunneling"),
|
||||||
|
("Remove", "Eltávolít"),
|
||||||
|
("Refresh random password", "Véletlenszerű jelszó frissítése"),
|
||||||
|
("Set your own password", "Saját jelszó beállítása"),
|
||||||
|
("Enable Keyboard/Mouse", "Billentyűzet/Egér bekapcsolása"),
|
||||||
|
("Enable Clipboard", "Megosztott vágólap bekapcsolása"),
|
||||||
|
("Enable File Transfer", "Fájl transzer bekapcsolása"),
|
||||||
|
("Enable TCP Tunneling", "TCP Tunneling bekapcsolása"),
|
||||||
|
("IP Whitelisting", "IP Fehérlista"),
|
||||||
|
("ID/Relay Server", "ID/Relay Szerver"),
|
||||||
|
("Stop service", "Szolgáltatás Kikapcsolása"),
|
||||||
|
("Change ID", "ID Megváltoztatása"),
|
||||||
|
("Website", "Weboldal"),
|
||||||
|
("About", "Rólunk: "),
|
||||||
|
("Mute", "Némítás"),
|
||||||
|
("Audio Input", "Audo Bemenet"),
|
||||||
|
("Enhancements", "Javítások"),
|
||||||
|
("Hardware Codec", "Hardware Kodek"),
|
||||||
|
("Adaptive Bitrate", "Adaptív Bitrate"),
|
||||||
|
("ID Server", "ID Szerver"),
|
||||||
|
("Relay Server", "Relay Szerver"),
|
||||||
|
("API Server", "API Szerver"),
|
||||||
|
("invalid_http", "A címnek mindenképpen http(s)://-el kell kezdődnie."),
|
||||||
|
("Invalid IP", "A megadott íp cím helytelen."),
|
||||||
|
("id_change_tip", "Csak a-z, A-Z, 0-9 csoportokba tartozó karakterek, illetve a _ karakter van engedélyezve. Az első karakternek mindenképpen a-z, A-Z csoportokba kell esnie. Az ID hosszúsága 6-tól, 16 karakter."),
|
||||||
|
("Invalid format", "Érvénytelen formátum"),
|
||||||
|
("server_not_support", "Még nem támogatott a szerver által"),
|
||||||
|
("Not available", "Nem érhető el"),
|
||||||
|
("Too frequent", "Túl gyakori"),
|
||||||
|
("Cancel", "Mégsem"),
|
||||||
|
("Skip", "Kihagy"),
|
||||||
|
("Close", "Bezár"),
|
||||||
|
("Retry", "Újrapróbálkozás"),
|
||||||
|
("OK", "OK"),
|
||||||
|
("Password Required", "A jelszó megadása kötelező"),
|
||||||
|
("Please enter your password", "Kérlek írd be a jelszavad"),
|
||||||
|
("Remember password", "Kérlek emlékezz a jelszóra"),
|
||||||
|
("Wrong Password", "Hibás jelszó"),
|
||||||
|
("Do you want to enter again?", "Újra szeretnéd próbálni?"),
|
||||||
|
("Connection Error", "Kapcsolódási Hiba"),
|
||||||
|
("Error", "Hiba"),
|
||||||
|
("Reset by the peer", "A kapcsolatot alaphelyzetbe állt"),
|
||||||
|
("Connecting...", "Kapcsolódás..."),
|
||||||
|
("Connection in progress. Please wait.", "A kapcsolódás folyamatban van. Kérlek várj."),
|
||||||
|
("Please try 1 minute later", "Kérlek próbáld újra 1 perc múlva."),
|
||||||
|
("Login Error", "Belépési Hiba"),
|
||||||
|
("Successful", "Sikeres"),
|
||||||
|
("Connected, waiting for image...", "Kapcsolódva, várakozás a képre..."),
|
||||||
|
("Name", "Név"),
|
||||||
|
("Type", "Fajta"),
|
||||||
|
("Modified", "Módosított"),
|
||||||
|
("Size", "Méret"),
|
||||||
|
("Show Hidden Files", "Rejtett Fájlok Mutatása"),
|
||||||
|
("Receive", "Kapni"),
|
||||||
|
("Send", "Küldeni"),
|
||||||
|
("Refresh File", "Fájlok Frissítése"),
|
||||||
|
("Local", "Lokális"),
|
||||||
|
("Remote", "Távoli"),
|
||||||
|
("Remote Computer", "Távoli Számítógép"),
|
||||||
|
("Local Computer", "Lokális Számítógép"),
|
||||||
|
("Confirm Delete", "Törlés Megerősítése"),
|
||||||
|
("Delete", "Törlés"),
|
||||||
|
("Properties", "Tulajdonságok"),
|
||||||
|
("Multi Select", "Több fájl kiválasztása"),
|
||||||
|
("Empty Directory", "Üres Könyvtár"),
|
||||||
|
("Not an empty directory", "Nem egy üres könyvtár"),
|
||||||
|
("Are you sure you want to delete this file?", "Biztosan törölni szeretnéd ezt a fájlt?"),
|
||||||
|
("Are you sure you want to delete this empty directory?", "Biztosan törölni szeretnéd ezt az üres könyvtárat?"),
|
||||||
|
("Are you sure you want to delete the file of this directory?", "Biztosan törölni szeretnéd a fájlokat ebben a könyvtárban?"),
|
||||||
|
("Do this for all conflicts", "Ezt tedd az összes konfliktussal"),
|
||||||
|
("This is irreversible!", "Ez a folyamat visszafordíthatatlan!"),
|
||||||
|
("Deleting", "A törlés folyamatban"),
|
||||||
|
("files", "fájlok"),
|
||||||
|
("Waiting", "Várunk"),
|
||||||
|
("Finished", "Végzett"),
|
||||||
|
("Speed", "Gyorsaság"),
|
||||||
|
("Custom Image Quality", "Egyedi Képminőség"),
|
||||||
|
("Privacy mode", "Inkognító mód"),
|
||||||
|
("Block user input", "Felhasználói input blokkokolása"),
|
||||||
|
("Unblock user input", "Felhasználói input blokkolásának feloldása"),
|
||||||
|
("Adjust Window", "Ablakméret beállítása"),
|
||||||
|
("Original", "Eredeti"),
|
||||||
|
("Shrink", "Zsugorított"),
|
||||||
|
("Stretch", "Nyújtott"),
|
||||||
|
("Good image quality", "Jó képminőség"),
|
||||||
|
("Balanced", "Balanszolt"),
|
||||||
|
("Optimize reaction time", "Válaszidő optimializálása"),
|
||||||
|
("Custom", "Egyedi"),
|
||||||
|
("Show remote cursor", "Távoli kurzor mutatása"),
|
||||||
|
("Show quality monitor", "Minőségi monitor mutatása"),
|
||||||
|
("Disable clipboard", "Vágólap Kikapcsolása"),
|
||||||
|
("Lock after session end", "Lezárás a session végén"),
|
||||||
|
("Insert", "Beszúrás"),
|
||||||
|
("Insert Lock", "Beszúrási Zároló"),
|
||||||
|
("Refresh", "Frissítés"),
|
||||||
|
("ID does not exist", "Ez az ID nem létezik"),
|
||||||
|
("Failed to connect to rendezvous server", "A randevú szerverhez való kapcsolódás sikertelen"),
|
||||||
|
("Please try later", "Kérlek próbád később"),
|
||||||
|
("Remote desktop is offline", "A távoli asztal offline"),
|
||||||
|
("Key mismatch", "Eltérés a kulcsokban"),
|
||||||
|
("Timeout", "Időtúllépés"),
|
||||||
|
("Failed to connect to relay server", "A relay szerverhez való kapcsolódás sikertelen"),
|
||||||
|
("Failed to connect via rendezvous server", "A randevú szerverrel való kapcsolódás sikertelen"),
|
||||||
|
("Failed to connect via relay server", "A relay szerverrel való kapcsolódás sikertelen"),
|
||||||
|
("Failed to make direct connection to remote desktop", "A távoli asztalhoz való direkt kapcsolódás sikertelen"),
|
||||||
|
("Set Password", "Jelszó Beállítása"),
|
||||||
|
("OS Password", "Operációs Rendszer Jelszavának Beállítása"),
|
||||||
|
("install_tip", "Az UAC (Felhasználói Fiók Felügyelet) miatt, a RustDesk nem fog rendesen funkcionálni mint távoli oldal néhány esetben. Hogy ezt kikerüld, vagy kikapcsold, kérlek nyomj rá a gombra ezalatt az üzenet alatt, hogy feltelepítsd a RustDesket a rendszerre."),
|
||||||
|
("Click to upgrade", "Kattints a frissítés telepítéséhez"),
|
||||||
|
("Click to download", "Kattints a letöltéshez"),
|
||||||
|
("Click to update", "Kattints a frissítés letöltéséhez"),
|
||||||
|
("Configure", "Beállítás"),
|
||||||
|
("config_acc", "Ahhoz hogy a RustDesket távolról irányítani tudd, \"Elérhetőségi\" jogokat kell adnod a RustDesk-nek."),
|
||||||
|
("config_screen", "Ahhoz hogy a RustDesket távolról irányítani tudd, \"Képernyőfelvételi\" jogokat kell adnod a RustDesk-nek."),
|
||||||
|
("Installing ...", "Telepítés..."),
|
||||||
|
("Install", "Telepítés"),
|
||||||
|
("Installation", "Telepítés"),
|
||||||
|
("Installation Path", "Telepítési útvonal"),
|
||||||
|
("Create start menu shortcuts", "Start menu parancsikon létrehozása"),
|
||||||
|
("Create desktop icon", "Asztali icon létrehozása"),
|
||||||
|
("agreement_tip", "Azzal hogy elindítod a telepítést, elfogadod a licenszszerződést."),
|
||||||
|
("Accept and Install", "Elfogadás és Telepítés"),
|
||||||
|
("End-user license agreement", "Felhasználói licencszerződés"),
|
||||||
|
("Generating ...", "Generálás..."),
|
||||||
|
("Your installation is lower version.", "A jelenleg feltelepített verzió régebbi."),
|
||||||
|
("not_close_tcp_tip", "Ne zárd be ezt az ablakot miközben a tunnelt használod"),
|
||||||
|
("Listening ...", "Halgazózás..."),
|
||||||
|
("Remote Host", "Távoli Host"),
|
||||||
|
("Remote Port", "Távoli Port"),
|
||||||
|
("Action", "Akció"),
|
||||||
|
("Add", "Add"),
|
||||||
|
("Local Port", "Lokális Port"),
|
||||||
|
("setup_server_tip", "Egy gyorsabb kapcsolatért, kérlek hostolj egy saját szervert"),
|
||||||
|
("Too short, at least 6 characters.", "Túl rövid, legalább 6 karakter"),
|
||||||
|
("The confirmation is not identical.", "A megerősítés nem volt azonos"),
|
||||||
|
("Permissions", "Jogok"),
|
||||||
|
("Accept", "Elfogad"),
|
||||||
|
("Dismiss", "Elutasít"),
|
||||||
|
("Disconnect", "Szétkapcsolás"),
|
||||||
|
("Allow using keyboard and mouse", "Billentyűzet és egér használatának engedélyezése"),
|
||||||
|
("Allow using clipboard", "Vágólap használatának engedélyezése"),
|
||||||
|
("Allow hearing sound", "Hang átvitelének engedélyezése"),
|
||||||
|
("Allow file copy and paste", "Fájlok másolásának és beillesztésének engedélyezése"),
|
||||||
|
("Connected", "Kapcsolódva"),
|
||||||
|
("Direct and encrypted connection", "Direkt, és titkosított kapcsolat"),
|
||||||
|
("Relayed and encrypted connection", "Relayelt, és titkosított kapcsolat"),
|
||||||
|
("Direct and unencrypted connection", "Direkt, és nem titkosított kapcsolat"),
|
||||||
|
("Relayed and unencrypted connection", "Rekayelt, és nem titkosított kapcsolat"),
|
||||||
|
("Enter Remote ID", "Kérlek írd be a távoli ID-t"),
|
||||||
|
("Enter your password", "Kérlek írd be a jelszavadat"),
|
||||||
|
("Logging in...", "A belépés folyamatban..."),
|
||||||
|
("Enable RDP session sharing", "Az RDP session megosztás engedélyezése"),
|
||||||
|
("Auto Login", "Automatikus Login"),
|
||||||
|
("Enable Direct IP Access", "Direkt IP elérés engedélyezése"),
|
||||||
|
("Rename", "Átnevezés"),
|
||||||
|
("Space", "Hely"),
|
||||||
|
("Create Desktop Shortcut", "Asztali Parancsikon Lértehozása"),
|
||||||
|
("Change Path", "Útvonal Megváltoztatása"),
|
||||||
|
("Create Folder", "Mappa Készítése"),
|
||||||
|
("Please enter the folder name", "Kérlek írd be a mappa nevét"),
|
||||||
|
("Fix it", "Kérlek javísd meg"),
|
||||||
|
("Warning", "Figyelem"),
|
||||||
|
("Login screen using Wayland is not supported", "A belépési kijelzővel a Wayland használata nem támogatott"),
|
||||||
|
("Reboot required", "Újraindítás szükséges"),
|
||||||
|
("Unsupported display server ", "Nem támogatott kijelző szerver"),
|
||||||
|
("x11 expected", "x11-re számítottt"),
|
||||||
|
("Port", "Port"),
|
||||||
|
("Settings", "Beállítások"),
|
||||||
|
("Username", "Felhasználónév"),
|
||||||
|
("Invalid port", "Érvénytelen port"),
|
||||||
|
("Closed manually by the peer", "A kapcsolat manuálisan be lett zárva a másik fél álltal"),
|
||||||
|
("Enable remote configuration modification", "Távoli konfiguráció módosítás engedélyezése"),
|
||||||
|
("Run without install", "Futtatás feltelepítés nélkül"),
|
||||||
|
("Always connected via relay", "Mindig relay által kapcsolódott"),
|
||||||
|
("Always connect via relay", "Mindig relay által kapcsolódik"),
|
||||||
|
("whitelist_tip", "Csak a fehérlistán lévő címek érhetnek el"),
|
||||||
|
("Login", "Belépés"),
|
||||||
|
("Logout", "Kilépés"),
|
||||||
|
("Tags", "Tagok"),
|
||||||
|
("Search ID", "ID keresés"),
|
||||||
|
("Current Wayland display server is not supported", "Jelenleg a Wayland display szerver nem támogatott"),
|
||||||
|
("whitelist_sep", "Ide jönnek a címek, vesző, pontosvessző, space, vagy új sorral elválasztva"),
|
||||||
|
("Add ID", "ID Hozzáadása"),
|
||||||
|
("Add Tag", "Tag Hozzáadása"),
|
||||||
|
("Unselect all tags", "Az összes tag kiválasztásának törlése"),
|
||||||
|
("Network error", "Hálózati hiba"),
|
||||||
|
("Username missed", "A felhasználónév kimaradt"),
|
||||||
|
("Password missed", "A jelszó kimaradt"),
|
||||||
|
("Wrong credentials", "Hibás felhasználónév vagy jelszó"),
|
||||||
|
("Edit Tag", "A tag(ok) szerkeztése"),
|
||||||
|
("Unremember Password", "A jelszó megjegyzésének törlése"),
|
||||||
|
("Favorites", "Kedvencek"),
|
||||||
|
("Add to Favorites", "Hozzáadás a kedvencekhez"),
|
||||||
|
("Remove from Favorites", "Eltávolítás a kedvencektől"),
|
||||||
|
("Empty", "Üres"),
|
||||||
|
("Invalid folder name", "Helytelen fájlnév"),
|
||||||
|
("Socks5 Proxy", "Socks5-ös Proxy"),
|
||||||
|
("Hostname", "Hostnév"),
|
||||||
|
("Discovered", "Felfedezés"),
|
||||||
|
("install_daemon_tip", "Ahhoz hogy a RustDesk bootkor elinduljon, telepítened kell a rendszer szolgáltatást."),
|
||||||
|
("Remote ID", "Távoli ID"),
|
||||||
|
("Paste", "Beillesztés"),
|
||||||
|
("Paste here?", "Beillesztés ide?"),
|
||||||
|
("Are you sure to close the connection?", "Biztos vagy benne hogy be szeretnéd zárni a kapcsolatot?"),
|
||||||
|
("Download new version", "Új verzó letöltése"),
|
||||||
|
("Touch mode", "Érintési mód bekapcsolása"),
|
||||||
|
("Mouse mode", "Egérhasználati mód bekapcsolása"),
|
||||||
|
("One-Finger Tap", "Egyújas érintés"),
|
||||||
|
("Left Mouse", "Baloldali Egér"),
|
||||||
|
("One-Long Tap", "Egy hosszú érintés"),
|
||||||
|
("Two-Finger Tap", "Két újas érintés"),
|
||||||
|
("Right Mouse", "Jobboldali Egér"),
|
||||||
|
("One-Finger Move", "Egyújas mozgatás"),
|
||||||
|
("Double Tap & Move", "Kétszeri érintés, és Mozgatás"),
|
||||||
|
("Mouse Drag", "Egérrel való húzás"),
|
||||||
|
("Three-Finger vertically", "Három ujj függőlegesen"),
|
||||||
|
("Mouse Wheel", "Egérgörgő"),
|
||||||
|
("Two-Finger Move", "Kátújas mozgatás"),
|
||||||
|
("Canvas Move", "Nézet Mozgatása"),
|
||||||
|
("Pinch to Zoom", "Húzd össze a nagyításhoz"),
|
||||||
|
("Canvas Zoom", "Nézet Nagyítása"),
|
||||||
|
("Reset canvas", "Nézet visszaállítása"),
|
||||||
|
("No permission of file transfer", "Nincs jogod fájl transzer indításához"),
|
||||||
|
("Note", "Megyjegyzés"),
|
||||||
|
("Connection", "Kapcsolat"),
|
||||||
|
("Share Screen", "Képernyőmegosztás"),
|
||||||
|
("CLOSE", "LETILT"),
|
||||||
|
("OPEN", "ENGEDÉLYEZ"),
|
||||||
|
("Chat", "Chat"),
|
||||||
|
("Total", "Összes"),
|
||||||
|
("items", "Tárgyak"),
|
||||||
|
("Selected", "Kiválasztott"),
|
||||||
|
("Screen Capture", "Képernyőrögzítés"),
|
||||||
|
("Input Control", "Input Kontrol"),
|
||||||
|
("Audio Capture", "Audió Rögzítés"),
|
||||||
|
("File Connection", "Fájlkapcsolat"),
|
||||||
|
("Screen Connection", "Új Vizuális Kapcsolat"),
|
||||||
|
("Do you accept?", "Elfogadod?"),
|
||||||
|
("Open System Setting", "Rendszer beállítások megnyitása"),
|
||||||
|
("How to get Android input permission?", "Hogyan állíthatok be Android input jogokat?"),
|
||||||
|
("android_input_permission_tip1", "Ahhoz hogy egy távoli eszköz kontolálhassa az Android eszközödet egérrel vagy érintéssel, jogot kell adnod a RustDesk-nek, hogy használja az \"Elérhetőségi\" szolgáltatást."),
|
||||||
|
("android_input_permission_tip2", "Kérlek navigálj a rendszer beállításaihoz, keresd meg vagy írd be hogy [Feltelepített Szolgáltatások], és kapcsold be a [RustDesk Input] szolgáltatást."),
|
||||||
|
("android_new_connection_tip", "Új kontrollálási kérés érkezett, amely irányítani szeretné az eszközöded."),
|
||||||
|
("android_service_will_start_tip", "A \"Képernyőrögzítés\" engedélyezése automatikusan elindítja majd a szolgáltatást, amely megengedi más eszközöknek hogy kérést kezdeményezzenek az eszköz felé."),
|
||||||
|
("android_stop_service_tip", "A szolgáltatás bezárása automatikusan szétkapcsol minden létező kapcsolatot."),
|
||||||
|
("android_version_audio_tip", "A jelenlegi Android verzió nem támogatja a hangrögzítést, kérlek frissíts legalább Android 10-re, vagy egy újabb verzióra."),
|
||||||
|
("android_start_service_tip", "Nyomj a [Szolgáltatás Indítása] opcióra, vagy adj [Képernyőrözítési] jogot az applikációnak hogy elindítsd a képernyőmegosztó szolgáltatást."),
|
||||||
|
("Account", "Fiók"),
|
||||||
|
("Overwrite", "Felülírás"),
|
||||||
|
("This file exists, skip or overwrite this file?", "Ez a fájl már létezik, skippeljünk, vagy felülírjuk ezt a fájlt?"),
|
||||||
|
("Quit", "Kilépés"),
|
||||||
|
("doc_mac_permission", "https://rustdesk.com/docs/hu/manual/mac/#enable-permissions"),
|
||||||
|
("Help", "Segítség"),
|
||||||
|
("Failed", "Sikertelen"),
|
||||||
|
("Succeeded", "Sikeres"),
|
||||||
|
("Someone turns on privacy mode, exit", "Valaki bekacsolta a privát módot, lépj ki"),
|
||||||
|
("Unsupported", "Nem támogatott"),
|
||||||
|
("Peer denied", "Elutasítva a távoli fél álltal"),
|
||||||
|
("Please install plugins", "Kérlek telepítsd a pluginokat"),
|
||||||
|
("Peer exit", "A távoli fél kilépett"),
|
||||||
|
("Failed to turn off", "Nem tudtuk kikapcsolni"),
|
||||||
|
("Turned off", "Kikapcsolva"),
|
||||||
|
("In privacy mode", "Belépés a privát módba"),
|
||||||
|
("Out privacy mode", "Kilépés a privát módból"),
|
||||||
|
("Language", "Nyelv"),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
|
].iter().cloned().collect();
|
||||||
|
}
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "Dalam mode privasi"),
|
("In privacy mode", "Dalam mode privasi"),
|
||||||
("Out privacy mode", "Keluar dari mode privasi"),
|
("Out privacy mode", "Keluar dari mode privasi"),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "In modalità privacy"),
|
("In privacy mode", "In modalità privacy"),
|
||||||
("Out privacy mode", "Fuori modalità privacy"),
|
("Out privacy mode", "Fuori modalità privacy"),
|
||||||
("Language", "Linguaggio"),
|
("Language", "Linguaggio"),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "No modo de privacidade"),
|
("In privacy mode", "No modo de privacidade"),
|
||||||
("Out privacy mode", "Fora do modo de privacidade"),
|
("Out privacy mode", "Fora do modo de privacidade"),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "В режиме конфиденциальности"),
|
("In privacy mode", "В режиме конфиденциальности"),
|
||||||
("Out privacy mode", "Выход из режима конфиденциальности"),
|
("Out privacy mode", "Выход из режима конфиденциальности"),
|
||||||
("Language", "Язык"),
|
("Language", "Язык"),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "V režime súkromia"),
|
("In privacy mode", "V režime súkromia"),
|
||||||
("Out privacy mode", "Mimo režimu súkromia"),
|
("Out privacy mode", "Mimo režimu súkromia"),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", ""),
|
("In privacy mode", ""),
|
||||||
("Out privacy mode", ""),
|
("Out privacy mode", ""),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "Gizlilik modunda"),
|
("In privacy mode", "Gizlilik modunda"),
|
||||||
("Out privacy mode", "Gizlilik modu dışında"),
|
("Out privacy mode", "Gizlilik modu dışında"),
|
||||||
("Language", ""),
|
("Language", ""),
|
||||||
|
("Keep RustDesk background service", ""),
|
||||||
|
("Ignore Battery Optimizations", ""),
|
||||||
|
("android_open_battery_optimizations_tip", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -284,5 +284,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("In privacy mode", "開啟隱私模式"),
|
("In privacy mode", "開啟隱私模式"),
|
||||||
("Out privacy mode", "退出隱私模式"),
|
("Out privacy mode", "退出隱私模式"),
|
||||||
("Language", "語言"),
|
("Language", "語言"),
|
||||||
|
("Keep RustDesk background service", "保持RustDesk後台服務"),
|
||||||
|
("Ignore Battery Optimizations", "忽略電池優化"),
|
||||||
|
("android_open_battery_optimizations_tip", "如需關閉此功能,請在接下來的RustDesk應用設置頁面中,找到並進入 [電源] 頁面,取消勾選 [不受限制]"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ mod client;
|
|||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
mod rendezvous_mediator;
|
mod rendezvous_mediator;
|
||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
|
mod lan;
|
||||||
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
pub use self::rendezvous_mediator::*;
|
pub use self::rendezvous_mediator::*;
|
||||||
/// cbindgen:ignore
|
/// cbindgen:ignore
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
@ -591,7 +591,6 @@ impl Connection {
|
|||||||
log::debug!("Exit io_loop of id={}", session.id);
|
log::debug!("Exit io_loop of id={}", session.id);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
crate::common::test_rendezvous_server();
|
|
||||||
session.msgbox("error", "Connection Error", &err.to_string());
|
session.msgbox("error", "Connection Error", &err.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -600,7 +599,7 @@ impl Connection {
|
|||||||
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 {
|
||||||
Some(message::Union::video_frame(vf)) => {
|
Some(message::Union::VideoFrame(vf)) => {
|
||||||
if !self.first_frame {
|
if !self.first_frame {
|
||||||
self.first_frame = true;
|
self.first_frame = true;
|
||||||
}
|
}
|
||||||
@ -611,21 +610,21 @@ impl Connection {
|
|||||||
s.add(ZeroCopyBuffer(self.video_handler.rgb.clone()));
|
s.add(ZeroCopyBuffer(self.video_handler.rgb.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(message::Union::hash(hash)) => {
|
Some(message::Union::Hash(hash)) => {
|
||||||
self.session.handle_hash(hash, peer).await;
|
self.session.handle_hash(hash, peer).await;
|
||||||
}
|
}
|
||||||
Some(message::Union::login_response(lr)) => match lr.union {
|
Some(message::Union::LoginResponse(lr)) => match lr.union {
|
||||||
Some(login_response::Union::error(err)) => {
|
Some(login_response::Union::Error(err)) => {
|
||||||
if !self.session.handle_login_error(&err) {
|
if !self.session.handle_login_error(&err) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(login_response::Union::peer_info(pi)) => {
|
Some(login_response::Union::PeerInfo(pi)) => {
|
||||||
self.session.handle_peer_info(pi);
|
self.session.handle_peer_info(pi);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Some(message::Union::clipboard(cb)) => {
|
Some(message::Union::Clipboard(cb)) => {
|
||||||
if !self.session.lc.read().unwrap().disable_clipboard {
|
if !self.session.lc.read().unwrap().disable_clipboard {
|
||||||
let content = if cb.compress {
|
let content = if cb.compress {
|
||||||
decompress(&cb.content)
|
decompress(&cb.content)
|
||||||
@ -638,7 +637,7 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(message::Union::cursor_data(cd)) => {
|
Some(message::Union::CursorData(cd)) => {
|
||||||
let colors = hbb_common::compress::decompress(&cd.colors);
|
let colors = hbb_common::compress::decompress(&cd.colors);
|
||||||
self.session.push_event(
|
self.session.push_event(
|
||||||
"cursor_data",
|
"cursor_data",
|
||||||
@ -655,18 +654,18 @@ impl Connection {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Some(message::Union::cursor_id(id)) => {
|
Some(message::Union::CursorId(id)) => {
|
||||||
self.session
|
self.session
|
||||||
.push_event("cursor_id", vec![("id", &id.to_string())]);
|
.push_event("cursor_id", vec![("id", &id.to_string())]);
|
||||||
}
|
}
|
||||||
Some(message::Union::cursor_position(cp)) => {
|
Some(message::Union::CursorPosition(cp)) => {
|
||||||
self.session.push_event(
|
self.session.push_event(
|
||||||
"cursor_position",
|
"cursor_position",
|
||||||
vec![("x", &cp.x.to_string()), ("y", &cp.y.to_string())],
|
vec![("x", &cp.x.to_string()), ("y", &cp.y.to_string())],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Some(message::Union::file_response(fr)) => match fr.union {
|
Some(message::Union::FileResponse(fr)) => match fr.union {
|
||||||
Some(file_response::Union::dir(fd)) => {
|
Some(file_response::Union::Dir(fd)) => {
|
||||||
let mut entries = fd.entries.to_vec();
|
let mut entries = fd.entries.to_vec();
|
||||||
if self.session.peer_platform() == "Windows" {
|
if self.session.peer_platform() == "Windows" {
|
||||||
fs::transform_windows_path(&mut entries);
|
fs::transform_windows_path(&mut entries);
|
||||||
@ -680,7 +679,7 @@ impl Connection {
|
|||||||
job.set_files(entries);
|
job.set_files(entries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(file_response::Union::block(block)) => {
|
Some(file_response::Union::Block(block)) => {
|
||||||
if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) {
|
if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) {
|
||||||
if let Err(_err) = job.write(block, None).await {
|
if let Err(_err) = job.write(block, None).await {
|
||||||
// to-do: add "skip" for writing job
|
// to-do: add "skip" for writing job
|
||||||
@ -688,17 +687,17 @@ impl Connection {
|
|||||||
self.update_jobs_status();
|
self.update_jobs_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(file_response::Union::done(d)) => {
|
Some(file_response::Union::Done(d)) => {
|
||||||
if let Some(job) = fs::get_job(d.id, &mut self.write_jobs) {
|
if let Some(job) = fs::get_job(d.id, &mut self.write_jobs) {
|
||||||
job.modify_time();
|
job.modify_time();
|
||||||
fs::remove_job(d.id, &mut self.write_jobs);
|
fs::remove_job(d.id, &mut self.write_jobs);
|
||||||
}
|
}
|
||||||
self.handle_job_status(d.id, d.file_num, None);
|
self.handle_job_status(d.id, d.file_num, None);
|
||||||
}
|
}
|
||||||
Some(file_response::Union::error(e)) => {
|
Some(file_response::Union::Error(e)) => {
|
||||||
self.handle_job_status(e.id, e.file_num, Some(e.error));
|
self.handle_job_status(e.id, e.file_num, Some(e.error));
|
||||||
}
|
}
|
||||||
Some(file_response::Union::digest(digest)) => {
|
Some(file_response::Union::Digest(digest)) => {
|
||||||
if digest.is_upload {
|
if digest.is_upload {
|
||||||
if let Some(job) = fs::get_job(digest.id, &mut self.read_jobs) {
|
if let Some(job) = fs::get_job(digest.id, &mut self.read_jobs) {
|
||||||
if let Some(file) = job.files().get(digest.file_num as usize) {
|
if let Some(file) = job.files().get(digest.file_num as usize) {
|
||||||
@ -709,9 +708,9 @@ impl Connection {
|
|||||||
id: digest.id,
|
id: digest.id,
|
||||||
file_num: digest.file_num,
|
file_num: digest.file_num,
|
||||||
union: Some(if overwrite {
|
union: Some(if overwrite {
|
||||||
file_transfer_send_confirm_request::Union::offset_blk(0)
|
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||||
} else {
|
} else {
|
||||||
file_transfer_send_confirm_request::Union::skip(
|
file_transfer_send_confirm_request::Union::Skip(
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
@ -741,7 +740,7 @@ impl Connection {
|
|||||||
let msg= new_send_confirm(FileTransferSendConfirmRequest {
|
let msg= new_send_confirm(FileTransferSendConfirmRequest {
|
||||||
id: digest.id,
|
id: digest.id,
|
||||||
file_num: digest.file_num,
|
file_num: digest.file_num,
|
||||||
union: Some(file_transfer_send_confirm_request::Union::skip(true)),
|
union: Some(file_transfer_send_confirm_request::Union::Skip(true)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
self.session.send_msg(msg);
|
self.session.send_msg(msg);
|
||||||
@ -753,9 +752,9 @@ impl Connection {
|
|||||||
id: digest.id,
|
id: digest.id,
|
||||||
file_num: digest.file_num,
|
file_num: digest.file_num,
|
||||||
union: Some(if overwrite {
|
union: Some(if overwrite {
|
||||||
file_transfer_send_confirm_request::Union::offset_blk(0)
|
file_transfer_send_confirm_request::Union::OffsetBlk(0)
|
||||||
} else {
|
} else {
|
||||||
file_transfer_send_confirm_request::Union::skip(true)
|
file_transfer_send_confirm_request::Union::Skip(true)
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -775,7 +774,7 @@ impl Connection {
|
|||||||
FileTransferSendConfirmRequest {
|
FileTransferSendConfirmRequest {
|
||||||
id: digest.id,
|
id: digest.id,
|
||||||
file_num: digest.file_num,
|
file_num: digest.file_num,
|
||||||
union: Some(file_transfer_send_confirm_request::Union::offset_blk(0)),
|
union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -792,15 +791,15 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Some(message::Union::misc(misc)) => match misc.union {
|
Some(message::Union::Misc(misc)) => match misc.union {
|
||||||
Some(misc::Union::audio_format(f)) => {
|
Some(misc::Union::AudioFormat(f)) => {
|
||||||
self.audio_handler.handle_format(f); //
|
self.audio_handler.handle_format(f); //
|
||||||
}
|
}
|
||||||
Some(misc::Union::chat_message(c)) => {
|
Some(misc::Union::ChatMessage(c)) => {
|
||||||
self.session
|
self.session
|
||||||
.push_event("chat_client_mode", vec![("text", &c.text)]);
|
.push_event("chat_client_mode", vec![("text", &c.text)]);
|
||||||
}
|
}
|
||||||
Some(misc::Union::permission_info(p)) => {
|
Some(misc::Union::PermissionInfo(p)) => {
|
||||||
log::info!("Change permission {:?} -> {}", p.permission, p.enabled);
|
log::info!("Change permission {:?} -> {}", p.permission, p.enabled);
|
||||||
use permission_info::Permission;
|
use permission_info::Permission;
|
||||||
self.session.push_event(
|
self.session.push_event(
|
||||||
@ -816,7 +815,7 @@ impl Connection {
|
|||||||
)],
|
)],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Some(misc::Union::switch_display(s)) => {
|
Some(misc::Union::SwitchDisplay(s)) => {
|
||||||
self.video_handler.reset();
|
self.video_handler.reset();
|
||||||
self.session.push_event(
|
self.session.push_event(
|
||||||
"switch_display",
|
"switch_display",
|
||||||
@ -829,22 +828,22 @@ impl Connection {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Some(misc::Union::close_reason(c)) => {
|
Some(misc::Union::CloseReason(c)) => {
|
||||||
self.session.msgbox("error", "Connection Error", &c);
|
self.session.msgbox("error", "Connection Error", &c);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Some(message::Union::test_delay(t)) => {
|
Some(message::Union::TestDelay(t)) => {
|
||||||
self.session.handle_test_delay(t, peer).await;
|
self.session.handle_test_delay(t, peer).await;
|
||||||
}
|
}
|
||||||
Some(message::Union::audio_frame(frame)) => {
|
Some(message::Union::AudioFrame(frame)) => {
|
||||||
if !self.session.lc.read().unwrap().disable_audio {
|
if !self.session.lc.read().unwrap().disable_audio {
|
||||||
self.audio_handler.handle_frame(frame);
|
self.audio_handler.handle_frame(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(message::Union::file_action(action)) => match action.union {
|
Some(message::Union::FileAction(action)) => match action.union {
|
||||||
Some(file_action::Union::send_confirm(c)) => {
|
Some(file_action::Union::SendConfirm(c)) => {
|
||||||
if let Some(job) = fs::get_job(c.id, &mut self.read_jobs) {
|
if let Some(job) = fs::get_job(c.id, &mut self.read_jobs) {
|
||||||
job.confirm(&c);
|
job.confirm(&c);
|
||||||
}
|
}
|
||||||
@ -1030,9 +1029,9 @@ impl Connection {
|
|||||||
id,
|
id,
|
||||||
file_num,
|
file_num,
|
||||||
union: if need_override {
|
union: if need_override {
|
||||||
Some(file_transfer_send_confirm_request::Union::offset_blk(0))
|
Some(file_transfer_send_confirm_request::Union::OffsetBlk(0))
|
||||||
} else {
|
} else {
|
||||||
Some(file_transfer_send_confirm_request::Union::skip(true))
|
Some(file_transfer_send_confirm_request::Union::Skip(true))
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
@ -1048,9 +1047,9 @@ impl Connection {
|
|||||||
id,
|
id,
|
||||||
file_num,
|
file_num,
|
||||||
union: if need_override {
|
union: if need_override {
|
||||||
Some(file_transfer_send_confirm_request::Union::offset_blk(0))
|
Some(file_transfer_send_confirm_request::Union::OffsetBlk(0))
|
||||||
} else {
|
} else {
|
||||||
Some(file_transfer_send_confirm_request::Union::skip(true))
|
Some(file_transfer_send_confirm_request::Union::Skip(true))
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
@ -1452,7 +1451,7 @@ pub mod connection_manager {
|
|||||||
let mut req = FileTransferSendConfirmRequest {
|
let mut req = FileTransferSendConfirmRequest {
|
||||||
id,
|
id,
|
||||||
file_num,
|
file_num,
|
||||||
union: Some(file_transfer_send_confirm_request::Union::offset_blk(0)),
|
union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let digest = FileTransferDigest {
|
let digest = FileTransferDigest {
|
||||||
|
@ -183,7 +183,7 @@ async fn run_forward(forward: Framed<TcpStream, BytesCodec>, stream: Stream) ->
|
|||||||
},
|
},
|
||||||
res = stream.next() => {
|
res = stream.next() => {
|
||||||
if let Some(Ok(bytes)) = res {
|
if let Some(Ok(bytes)) = res {
|
||||||
allow_err!(forward.send(bytes.into()).await);
|
allow_err!(forward.send(bytes).await);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use crate::server::{check_zombie, new as new_server, ServerPtr};
|
|||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err,
|
allow_err,
|
||||||
anyhow::bail,
|
anyhow::bail,
|
||||||
config::{self, Config, REG_INTERVAL, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT},
|
config::{Config, REG_INTERVAL, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT},
|
||||||
futures::future::join_all,
|
futures::future::join_all,
|
||||||
log,
|
log,
|
||||||
protobuf::Message as _,
|
protobuf::Message as _,
|
||||||
@ -51,9 +51,12 @@ impl RendezvousMediator {
|
|||||||
check_zombie();
|
check_zombie();
|
||||||
let server = new_server();
|
let server = new_server();
|
||||||
if Config::get_nat_type() == NatType::UNKNOWN_NAT as i32 {
|
if Config::get_nat_type() == NatType::UNKNOWN_NAT as i32 {
|
||||||
crate::common::test_nat_type();
|
crate::test_nat_type();
|
||||||
nat_tested = true;
|
nat_tested = true;
|
||||||
}
|
}
|
||||||
|
if !Config::get_option("stop-service").is_empty() {
|
||||||
|
crate::test_rendezvous_server();
|
||||||
|
}
|
||||||
let server_cloned = server.clone();
|
let server_cloned = server.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
direct_server(server_cloned).await;
|
direct_server(server_cloned).await;
|
||||||
@ -61,14 +64,14 @@ impl RendezvousMediator {
|
|||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
if crate::platform::is_installed() {
|
if crate::platform::is_installed() {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
allow_err!(lan_discovery());
|
allow_err!(super::lan::start_listening());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
Config::reset_online();
|
Config::reset_online();
|
||||||
if Config::get_option("stop-service").is_empty() {
|
if Config::get_option("stop-service").is_empty() {
|
||||||
if !nat_tested {
|
if !nat_tested {
|
||||||
crate::common::test_nat_type();
|
crate::test_nat_type();
|
||||||
nat_tested = true;
|
nat_tested = true;
|
||||||
}
|
}
|
||||||
let mut futs = Vec::new();
|
let mut futs = Vec::new();
|
||||||
@ -537,103 +540,3 @@ async fn direct_server(server: ServerPtr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_broadcast_port() -> u16 {
|
|
||||||
(RENDEZVOUS_PORT + 3) as _
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mac() -> String {
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
|
||||||
if let Ok(Some(mac)) = mac_address::get_mac_address() {
|
|
||||||
mac.to_string()
|
|
||||||
} else {
|
|
||||||
"".to_owned()
|
|
||||||
}
|
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
|
||||||
"".to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lan_discovery() -> ResultType<()> {
|
|
||||||
let addr = SocketAddr::from(([0, 0, 0, 0], get_broadcast_port()));
|
|
||||||
let socket = std::net::UdpSocket::bind(addr)?;
|
|
||||||
socket.set_read_timeout(Some(std::time::Duration::from_millis(1000)))?;
|
|
||||||
log::info!("lan discovery listener started");
|
|
||||||
loop {
|
|
||||||
let mut buf = [0; 2048];
|
|
||||||
if let Ok((len, addr)) = socket.recv_from(&mut buf) {
|
|
||||||
if let Ok(msg_in) = Message::parse_from_bytes(&buf[0..len]) {
|
|
||||||
match msg_in.union {
|
|
||||||
Some(rendezvous_message::Union::PeerDiscovery(p)) => {
|
|
||||||
if p.cmd == "ping" {
|
|
||||||
let mut msg_out = Message::new();
|
|
||||||
let peer = PeerDiscovery {
|
|
||||||
cmd: "pong".to_owned(),
|
|
||||||
mac: get_mac(),
|
|
||||||
id: Config::get_id(),
|
|
||||||
hostname: whoami::hostname(),
|
|
||||||
username: crate::platform::get_active_username(),
|
|
||||||
platform: whoami::platform().to_string(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
msg_out.set_peer_discovery(peer);
|
|
||||||
socket.send_to(&msg_out.write_to_bytes()?, addr).ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn discover() -> ResultType<()> {
|
|
||||||
let addr = SocketAddr::from(([0, 0, 0, 0], 0));
|
|
||||||
let socket = std::net::UdpSocket::bind(addr)?;
|
|
||||||
socket.set_broadcast(true)?;
|
|
||||||
let mut msg_out = Message::new();
|
|
||||||
let peer = PeerDiscovery {
|
|
||||||
cmd: "ping".to_owned(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
msg_out.set_peer_discovery(peer);
|
|
||||||
let maddr = SocketAddr::from(([255, 255, 255, 255], get_broadcast_port()));
|
|
||||||
socket.send_to(&msg_out.write_to_bytes()?, maddr)?;
|
|
||||||
log::info!("discover ping sent");
|
|
||||||
let mut last_recv_time = Instant::now();
|
|
||||||
let mut last_write_time = Instant::now();
|
|
||||||
let mut last_write_n = 0;
|
|
||||||
// to-do: load saved peers, and update incrementally (then we can see offline)
|
|
||||||
let mut peers = Vec::new();
|
|
||||||
let mac = get_mac();
|
|
||||||
socket.set_read_timeout(Some(std::time::Duration::from_millis(10)))?;
|
|
||||||
loop {
|
|
||||||
let mut buf = [0; 2048];
|
|
||||||
if let Ok((len, _)) = socket.recv_from(&mut buf) {
|
|
||||||
if let Ok(msg_in) = Message::parse_from_bytes(&buf[0..len]) {
|
|
||||||
match msg_in.union {
|
|
||||||
Some(rendezvous_message::Union::PeerDiscovery(p)) => {
|
|
||||||
last_recv_time = Instant::now();
|
|
||||||
if p.cmd == "pong" {
|
|
||||||
if p.mac != mac {
|
|
||||||
peers.push((p.id, p.username, p.hostname, p.platform));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if last_write_time.elapsed().as_millis() > 300 && last_write_n != peers.len() {
|
|
||||||
config::LanPeers::store(serde_json::to_string(&peers)?);
|
|
||||||
last_write_time = Instant::now();
|
|
||||||
last_write_n = peers.len();
|
|
||||||
}
|
|
||||||
if last_recv_time.elapsed().as_millis() > 3_000 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log::info!("discover ping done");
|
|
||||||
config::LanPeers::store(serde_json::to_string(&peers)?);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
@ -492,7 +492,7 @@ impl Connection {
|
|||||||
res = self.stream.next() => {
|
res = self.stream.next() => {
|
||||||
if let Some(res) = res {
|
if let Some(res) = res {
|
||||||
last_recv_time = Instant::now();
|
last_recv_time = Instant::now();
|
||||||
timeout(SEND_TIMEOUT_OTHER, forward.send(res?.into())).await??;
|
timeout(SEND_TIMEOUT_OTHER, forward.send(res?)).await??;
|
||||||
} else {
|
} else {
|
||||||
bail!("Stream reset by the peer");
|
bail!("Stream reset by the peer");
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,6 @@ impl VideoQoS {
|
|||||||
// handle image_quality change from peer
|
// handle image_quality change from peer
|
||||||
pub fn update_image_quality(&mut self, image_quality: i32) {
|
pub fn update_image_quality(&mut self, image_quality: i32) {
|
||||||
let image_quality = Self::convert_quality(image_quality) as _;
|
let image_quality = Self::convert_quality(image_quality) as _;
|
||||||
log::debug!("VideoQoS update_image_quality: {}", image_quality);
|
|
||||||
if self.current_image_quality != image_quality {
|
if self.current_image_quality != image_quality {
|
||||||
self.current_image_quality = image_quality;
|
self.current_image_quality = image_quality;
|
||||||
let _ = self.generate_bitrate().ok();
|
let _ = self.generate_bitrate().ok();
|
||||||
@ -171,7 +170,7 @@ impl VideoQoS {
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
{
|
{
|
||||||
// fix when andorid screen shrinks
|
// fix when andorid screen shrinks
|
||||||
let fix = Display::fix_quality() as u32;
|
let fix = scrap::Display::fix_quality() as u32;
|
||||||
log::debug!("Android screen, fix quality:{}", fix);
|
log::debug!("Android screen, fix quality:{}", fix);
|
||||||
let base_bitrate = base_bitrate * fix;
|
let base_bitrate = base_bitrate * fix;
|
||||||
self.target_bitrate = base_bitrate * self.current_image_quality / 100;
|
self.target_bitrate = base_bitrate * self.current_image_quality / 100;
|
||||||
|
16
src/ui.rs
16
src/ui.rs
@ -541,6 +541,16 @@ impl UI {
|
|||||||
PeerConfig::remove(&id);
|
PeerConfig::remove(&id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_discovered(&mut self, id: String) {
|
||||||
|
let mut peers = config::LanPeers::load().peers;
|
||||||
|
peers.retain(|x| x.id != id);
|
||||||
|
config::LanPeers::store(&peers);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_wol(&mut self, id: String) {
|
||||||
|
crate::lan::send_wol(id)
|
||||||
|
}
|
||||||
|
|
||||||
fn new_remote(&mut self, id: String, remote_type: String) {
|
fn new_remote(&mut self, id: String, remote_type: String) {
|
||||||
let mut lock = self.0.lock().unwrap();
|
let mut lock = self.0.lock().unwrap();
|
||||||
let args = vec![format!("--{}", remote_type), id.clone()];
|
let args = vec![format!("--{}", remote_type), id.clone()];
|
||||||
@ -685,12 +695,12 @@ impl UI {
|
|||||||
|
|
||||||
fn discover(&self) {
|
fn discover(&self) {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
allow_err!(crate::rendezvous_mediator::discover());
|
allow_err!(crate::lan::discover());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lan_peers(&self) -> String {
|
fn get_lan_peers(&self) -> String {
|
||||||
config::LanPeers::load().peers
|
serde_json::to_string(&config::LanPeers::load().peers).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_uuid(&self) -> String {
|
fn get_uuid(&self) -> String {
|
||||||
@ -780,7 +790,9 @@ impl sciter::EventHandler for UI {
|
|||||||
fn closing(i32, i32, i32, i32);
|
fn closing(i32, i32, i32, i32);
|
||||||
fn get_size();
|
fn get_size();
|
||||||
fn new_remote(String, bool);
|
fn new_remote(String, bool);
|
||||||
|
fn send_wol(String);
|
||||||
fn remove_peer(String);
|
fn remove_peer(String);
|
||||||
|
fn remove_discovered(String);
|
||||||
fn get_connect_status();
|
fn get_connect_status();
|
||||||
fn get_mouse_time();
|
fn get_mouse_time();
|
||||||
fn check_mouse_time();
|
fn check_mouse_time();
|
||||||
|
@ -318,9 +318,10 @@ class SessionList: Reactor.Component {
|
|||||||
<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>}
|
{false && !handler.using_public_server() && <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>
|
||||||
<div .separator />
|
<div .separator />
|
||||||
<li #rename>{translate('Rename')}</li>
|
{this.type != "lan" && <li #rename>{translate('Rename')}</li>}
|
||||||
{this.type != "fav" && this.type != "lan" && <li #remove>{translate('Remove')}</li>}
|
{this.type != "fav" && <li #remove>{translate('Remove')}</li>}
|
||||||
{is_win && <li #shortcut>{translate('Create Desktop Shortcut')}</li>}
|
{is_win && <li #shortcut>{translate('Create Desktop Shortcut')}</li>}
|
||||||
<li #forget-password>{translate('Unremember Password')}</li>
|
<li #forget-password>{translate('Unremember Password')}</li>
|
||||||
{(!this.type || this.type == "fav") && <li #add-fav>{translate('Add to Favorites')}</li>}
|
{(!this.type || this.type == "fav") && <li #add-fav>{translate('Add to Favorites')}</li>}
|
||||||
@ -419,6 +420,8 @@ class SessionList: Reactor.Component {
|
|||||||
createNewConnect(id, "connect");
|
createNewConnect(id, "connect");
|
||||||
} else if (action == "transfer") {
|
} else if (action == "transfer") {
|
||||||
createNewConnect(id, "file-transfer");
|
createNewConnect(id, "file-transfer");
|
||||||
|
} else if (action == "wol") {
|
||||||
|
handler.send_wol(id);
|
||||||
} else if (action == "remove") {
|
} else if (action == "remove") {
|
||||||
if (this.type == "ab") {
|
if (this.type == "ab") {
|
||||||
for (var i = 0; i < ab.peers.length; ++i) {
|
for (var i = 0; i < ab.peers.length; ++i) {
|
||||||
@ -429,6 +432,9 @@ class SessionList: Reactor.Component {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (this.type == "lan") {
|
||||||
|
handler.remove_discovered(id);
|
||||||
|
app.update();
|
||||||
} else {
|
} else {
|
||||||
handler.remove_peer(id);
|
handler.remove_peer(id);
|
||||||
app.update();
|
app.update();
|
||||||
|
@ -258,10 +258,10 @@ pub fn check_main_window() {
|
|||||||
let app = format!("/Applications/{}.app", crate::get_app_name());
|
let app = format!("/Applications/{}.app", crate::get_app_name());
|
||||||
let my_uid = sys
|
let my_uid = sys
|
||||||
.process((std::process::id() as i32).into())
|
.process((std::process::id() as i32).into())
|
||||||
.map(|x| x.uid)
|
.map(|x| x.user_id())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
for (_, p) in sys.processes().iter() {
|
for (_, p) in sys.processes().iter() {
|
||||||
if p.cmd().len() == 1 && p.uid == my_uid && p.cmd()[0].contains(&app) {
|
if p.cmd().len() == 1 && p.user_id() == my_uid && p.cmd()[0].contains(&app) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user