Merge branch 'master' into sort-favorites
This commit is contained in:
commit
04bd8e167a
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -6,7 +6,7 @@ body:
|
||||
id: desc
|
||||
attributes:
|
||||
label: Bug Description
|
||||
description: A clear and concise description of what the bug is
|
||||
description: A clear and concise description of what the bug is (if it's a keyboard issue, provide the keyboard mode you're using. e.g. legacy, map, translate)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
1939
Cargo.lock
generated
1939
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
17
Cargo.toml
17
Cargo.toml
@ -45,22 +45,22 @@ lazy_static = "1.4"
|
||||
sha2 = "0.10"
|
||||
repng = "0.2"
|
||||
parity-tokio-ipc = { git = "https://github.com/open-trade/parity-tokio-ipc" }
|
||||
runas = "0.2"
|
||||
runas = "1.0"
|
||||
magnum-opus = { git = "https://github.com/rustdesk/magnum-opus" }
|
||||
dasp = { version = "0.11", features = ["signal", "interpolate-linear", "interpolate"], optional = true }
|
||||
rubato = { version = "0.12", optional = true }
|
||||
samplerate = { version = "0.2", optional = true }
|
||||
async-trait = "0.1"
|
||||
uuid = { version = "1.0", features = ["v4"] }
|
||||
clap = "3.0"
|
||||
clap = "4.1"
|
||||
rpassword = "7.0"
|
||||
base64 = "0.13"
|
||||
base64 = "0.21"
|
||||
num_cpus = "1.13"
|
||||
bytes = { version = "1.2", features = ["serde"] }
|
||||
default-net = "0.12.0"
|
||||
wol-rs = "0.9.1"
|
||||
wol-rs = "1.0"
|
||||
flutter_rust_bridge = { version = "1.61.1", optional = true }
|
||||
errno = "0.2.8"
|
||||
errno = "0.3"
|
||||
rdev = { git = "https://github.com/fufesou/rdev" }
|
||||
url = { version = "2.1", features = ["serde"] }
|
||||
dlopen = "0.1"
|
||||
@ -71,7 +71,7 @@ chrono = "0.4.23"
|
||||
cidr-utils = "0.5.9"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
|
||||
cpal = "0.13.5"
|
||||
cpal = "0.14"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
machine-uid = "0.2"
|
||||
@ -81,9 +81,9 @@ sys-locale = "0.2"
|
||||
enigo = { path = "libs/enigo", features = [ "with_serde" ] }
|
||||
clipboard = { path = "libs/clipboard" }
|
||||
ctrlc = "3.2"
|
||||
arboard = "2.0"
|
||||
arboard = "3.2"
|
||||
#minreq = { version = "2.4", features = ["punycode", "https-native"] }
|
||||
system_shutdown = "3.0.0"
|
||||
system_shutdown = "4.0"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
trayicon = { git = "https://github.com/open-trade/trayicon-rs", features = ["winit"] }
|
||||
@ -148,6 +148,7 @@ cc = "1.0"
|
||||
hbb_common = { path = "libs/hbb_common" }
|
||||
simple_rc = { path = "libs/simple_rc", optional = true }
|
||||
flutter_rust_bridge_codegen = "1.61.1"
|
||||
os-version = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
hound = "3.5"
|
||||
|
9
build.rs
9
build.rs
@ -9,7 +9,14 @@ fn build_windows() {
|
||||
#[cfg(target_os = "macos")]
|
||||
fn build_mac() {
|
||||
let file = "src/platform/macos.mm";
|
||||
cc::Build::new().file(file).compile("macos");
|
||||
let mut b = cc::Build::new();
|
||||
if let Ok(os_version::OsVersion::MacOS(v)) = os_version::detect() {
|
||||
let v = v.version;
|
||||
if v.contains("10.14") {
|
||||
b.flag("-DNO_InputMonitoringAuthStatus=1");
|
||||
}
|
||||
}
|
||||
b.file(file).compile("macos");
|
||||
println!("cargo:rerun-if-changed={}", file);
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,9 @@
|
||||
| Σεούλ | AWS lightsail | 1 vCPU / 0.5GB RAM |
|
||||
| Γερμανία | Hetzner | 2 vCPU / 4GB RAM |
|
||||
| Γερμανία | Codext | 4 vCPU / 8GB RAM |
|
||||
| Φινλανδία (Ελσίνκι) | 0x101 Cyber Security | 4 vCPU / 8GB RAM |
|
||||
| ΗΠΑ (Άσμπερν) | 0x101 Cyber Security | 4 vCPU / 8GB RAM |
|
||||
| Ουκρανία (Κίεβο) | dc.volia (2VM) | 2 vCPU / 4GB RAM |
|
||||
| Φινλανδία (Ελσίνκι) | [Netlock](https://netlockendpoint.com) | 4 vCPU / 8GB RAM |
|
||||
| ΗΠΑ (Άσμπερν) | [Netlock](https://netlockendpoint.com) | 4 vCPU / 8GB RAM |
|
||||
| Ουκρανία (Κίεβο) | [dc.volia](https://dc.volia.com) | 2 vCPU / 4GB RAM |
|
||||
|
||||
## Dev Container
|
||||
|
||||
|
@ -430,7 +430,7 @@ final ButtonStyle flatButtonStyle = TextButton.styleFrom(
|
||||
);
|
||||
|
||||
List<Locale> supportedLocales = const [
|
||||
// specify CN/TW to fix CJK issue in flutter
|
||||
Locale('en', 'US'),
|
||||
Locale('zh', 'CN'),
|
||||
Locale('zh', 'TW'),
|
||||
Locale('zh', 'SG'),
|
||||
@ -452,7 +452,7 @@ List<Locale> supportedLocales = const [
|
||||
Locale('vi'),
|
||||
Locale('pl'),
|
||||
Locale('kz'),
|
||||
Locale('en', 'US'),
|
||||
Locale('es'),
|
||||
];
|
||||
|
||||
String formatDurationToTime(Duration duration) {
|
||||
|
@ -68,7 +68,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
||||
var _lastChangeTime = DateTime.now();
|
||||
var _lastQueryPeers = <String>{};
|
||||
var _lastQueryTime = DateTime.now().subtract(const Duration(hours: 1));
|
||||
var _queryCoun = 0;
|
||||
var _queryCount = 0;
|
||||
var _exit = false;
|
||||
|
||||
late final mobileWidth = () {
|
||||
@ -101,12 +101,12 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
||||
|
||||
@override
|
||||
void onWindowFocus() {
|
||||
_queryCoun = 0;
|
||||
_queryCount = 0;
|
||||
}
|
||||
|
||||
@override
|
||||
void onWindowMinimize() {
|
||||
_queryCoun = _maxQueryCount;
|
||||
_queryCount = _maxQueryCount;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -123,6 +123,19 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
||||
);
|
||||
}
|
||||
|
||||
onVisibilityChanged(VisibilityInfo info) {
|
||||
final peerId = _peerId((info.key as ValueKey).value);
|
||||
if (info.visibleFraction > 0.00001) {
|
||||
_curPeers.add(peerId);
|
||||
} else {
|
||||
_curPeers.remove(peerId);
|
||||
}
|
||||
_lastChangeTime = DateTime.now();
|
||||
}
|
||||
|
||||
String _cardId(String id) => widget.peers.name + id;
|
||||
String _peerId(String cardId) => cardId.replaceAll(widget.peers.name, '');
|
||||
|
||||
Widget _buildPeersView(Peers peers) {
|
||||
final body = ObxValue<RxList>((filters) {
|
||||
return FutureBuilder<List<Peer>>(
|
||||
@ -132,16 +145,8 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
||||
final cards = <Widget>[];
|
||||
for (final peer in peers) {
|
||||
final visibilityChild = VisibilityDetector(
|
||||
key: ValueKey(peer.id),
|
||||
onVisibilityChanged: (info) {
|
||||
final peerId = (info.key as ValueKey).value;
|
||||
if (info.visibleFraction > 0.00001) {
|
||||
_curPeers.add(peerId);
|
||||
} else {
|
||||
_curPeers.remove(peerId);
|
||||
}
|
||||
_lastChangeTime = DateTime.now();
|
||||
},
|
||||
key: ValueKey(_cardId(peer.id)),
|
||||
onVisibilityChanged: onVisibilityChanged,
|
||||
child: widget.peerCardBuilder(peer),
|
||||
);
|
||||
cards.add(isDesktop
|
||||
@ -172,6 +177,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
||||
// ignore: todo
|
||||
// TODO: variables walk through async tasks?
|
||||
void _startCheckOnlines() {
|
||||
final queryInterval = const Duration(seconds: 20);
|
||||
() async {
|
||||
while (!_exit) {
|
||||
final now = DateTime.now();
|
||||
@ -181,18 +187,18 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
|
||||
platformFFI.ffiBind
|
||||
.queryOnlines(ids: _curPeers.toList(growable: false));
|
||||
_lastQueryPeers = {..._curPeers};
|
||||
_lastQueryTime = DateTime.now();
|
||||
_queryCoun = 0;
|
||||
_lastQueryTime = DateTime.now().subtract(queryInterval);
|
||||
_queryCount = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_queryCoun < _maxQueryCount) {
|
||||
if (now.difference(_lastQueryTime) > const Duration(seconds: 20)) {
|
||||
if (_queryCount < _maxQueryCount) {
|
||||
if (now.difference(_lastQueryTime) >= queryInterval) {
|
||||
if (_curPeers.isNotEmpty) {
|
||||
platformFFI.ffiBind
|
||||
.queryOnlines(ids: _curPeers.toList(growable: false));
|
||||
_lastQueryTime = DateTime.now();
|
||||
_queryCoun += 1;
|
||||
_queryCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -166,17 +166,18 @@ class FfiModel with ChangeNotifier {
|
||||
} else if (name == 'file_dir') {
|
||||
parent.target?.fileModel.receiveFileDir(evt);
|
||||
} else if (name == 'job_progress') {
|
||||
parent.target?.fileModel.tryUpdateJobProgress(evt);
|
||||
parent.target?.fileModel.jobController.tryUpdateJobProgress(evt);
|
||||
} else if (name == 'job_done') {
|
||||
parent.target?.fileModel.jobDone(evt);
|
||||
parent.target?.fileModel.jobController.jobDone(evt);
|
||||
parent.target?.fileModel.refreshAll();
|
||||
} else if (name == 'job_error') {
|
||||
parent.target?.fileModel.jobError(evt);
|
||||
parent.target?.fileModel.jobController.jobError(evt);
|
||||
} else if (name == 'override_file_confirm') {
|
||||
parent.target?.fileModel.overrideFileConfirm(evt);
|
||||
} else if (name == 'load_last_job') {
|
||||
parent.target?.fileModel.loadLastJob(evt);
|
||||
parent.target?.fileModel.jobController.loadLastJob(evt);
|
||||
} else if (name == 'update_folder_files') {
|
||||
parent.target?.fileModel.updateFolderFiles(evt);
|
||||
parent.target?.fileModel.jobController.updateFolderFiles(evt);
|
||||
} else if (name == 'add_connection') {
|
||||
parent.target?.serverModel.addConnection(evt);
|
||||
} else if (name == 'on_client_remove') {
|
||||
@ -371,7 +372,11 @@ class FfiModel with ChangeNotifier {
|
||||
|
||||
_updateSessionWidthHeight(String id) {
|
||||
parent.target?.canvasModel.updateViewStyle();
|
||||
bind.sessionSetSize(id: id, width: display.width, height: display.height);
|
||||
if (display.width <= 0 || display.height <= 0) {
|
||||
debugPrintStack(label: 'invalid display size (${display.width},${display.height})');
|
||||
} else {
|
||||
bind.sessionSetSize(id: id, width: display.width, height: display.height);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle the peer info event based on [evt].
|
||||
@ -1571,9 +1576,6 @@ class FFI {
|
||||
}();
|
||||
// every instance will bind a stream
|
||||
this.id = id;
|
||||
if (isFileTransfer) {
|
||||
fileModel.initFileFetcher();
|
||||
}
|
||||
}
|
||||
|
||||
/// Login with [password], choose if the client should [remember] it.
|
||||
|
@ -28,10 +28,9 @@ class StateGlobal {
|
||||
|
||||
setWindowId(int id) => _windowId = id;
|
||||
setMaximize(bool v) {
|
||||
if (_maximize != v) {
|
||||
if (_maximize != v && !_fullscreen) {
|
||||
_maximize = v;
|
||||
_resizeEdgeSize.value =
|
||||
_maximize ? kMaximizeEdgeSize : kWindowEdgeSize;
|
||||
_resizeEdgeSize.value = _maximize ? kMaximizeEdgeSize : kWindowEdgeSize;
|
||||
}
|
||||
}
|
||||
setFullscreen(bool v) {
|
||||
@ -39,7 +38,13 @@ class StateGlobal {
|
||||
_fullscreen = v;
|
||||
_showTabBar.value = !_fullscreen;
|
||||
_resizeEdgeSize.value =
|
||||
fullscreen ? kFullScreenEdgeSize : kWindowEdgeSize;
|
||||
fullscreen
|
||||
? kFullScreenEdgeSize
|
||||
: _maximize
|
||||
? kMaximizeEdgeSize
|
||||
: kWindowEdgeSize;
|
||||
print(
|
||||
"fullscreen: ${fullscreen}, resizeEdgeSize: ${_resizeEdgeSize.value}");
|
||||
_windowBorderWidth.value = fullscreen ? 0 : kWindowBorderWidth;
|
||||
WindowController.fromWindowId(windowId)
|
||||
.setFullscreen(_fullscreen)
|
||||
|
@ -59,7 +59,7 @@ dependencies:
|
||||
desktop_multi_window:
|
||||
git:
|
||||
url: https://github.com/Kingtous/rustdesk_desktop_multi_window
|
||||
ref: 3e2655677c54f421f9e378680d8171b95a211e0f
|
||||
ref: e3947d4b4f8edaa655de63cd47f2a59a6e024218
|
||||
freezed_annotation: ^2.0.3
|
||||
flutter_custom_cursor: ^0.0.4
|
||||
window_size:
|
||||
|
@ -7,17 +7,17 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
flexi_logger = { version = "0.22", features = ["async", "use_chrono_for_offset"] }
|
||||
flexi_logger = { version = "0.25", features = ["async"] }
|
||||
protobuf = { version = "3.1", features = ["with-bytes"] }
|
||||
tokio = { version = "1.20", features = ["full"] }
|
||||
tokio-util = { version = "0.7", features = ["full"] }
|
||||
futures = "0.3"
|
||||
bytes = { version = "1.2", features = ["serde"] }
|
||||
log = "0.4"
|
||||
env_logger = "0.9"
|
||||
env_logger = "0.10"
|
||||
socket2 = { version = "0.3", features = ["reuseport"] }
|
||||
zstd = "0.9"
|
||||
quinn = {version = "0.8", optional = true }
|
||||
quinn = {version = "0.9", optional = true }
|
||||
anyhow = "1.0"
|
||||
futures-util = "0.3"
|
||||
directories-next = "2.0"
|
||||
@ -34,7 +34,7 @@ tokio-socks = { git = "https://github.com/open-trade/tokio-socks" }
|
||||
chrono = "0.4"
|
||||
backtrace = "0.3"
|
||||
libc = "0.2"
|
||||
sysinfo = "0.24"
|
||||
sysinfo = "0.26"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
mac_address = "1.1"
|
||||
@ -54,5 +54,5 @@ winapi = { version = "0.3", features = ["winuser"] }
|
||||
osascript = "0.3.0"
|
||||
|
||||
[dev-dependencies]
|
||||
toml = "0.5"
|
||||
toml = "0.7"
|
||||
serde_json = "1.0"
|
@ -4,7 +4,7 @@ use std::{
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
time::SystemTime,
|
||||
time::{Duration, Instant, SystemTime},
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
@ -51,6 +51,7 @@ lazy_static::lazy_static! {
|
||||
pub static ref APP_NAME: Arc<RwLock<String>> = Arc::new(RwLock::new("RustDesk".to_owned()));
|
||||
static ref KEY_PAIR: Arc<Mutex<Option<KeyPair>>> = Default::default();
|
||||
static ref HW_CODEC_CONFIG: Arc<RwLock<HwCodecConfig>> = Arc::new(RwLock::new(HwCodecConfig::load()));
|
||||
static ref USER_DEFAULT_CONFIG: Arc<RwLock<(UserDefaultConfig, Instant)>> = Arc::new(RwLock::new((UserDefaultConfig::load(), Instant::now())));
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
@ -123,7 +124,7 @@ macro_rules! serde_field_bool {
|
||||
}
|
||||
impl $struct_name {
|
||||
pub fn $func() -> bool {
|
||||
UserDefaultConfig::load().get($field_name) == "Y"
|
||||
UserDefaultConfig::read().get($field_name) == "Y"
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -980,21 +981,21 @@ impl PeerConfig {
|
||||
serde_field_string!(
|
||||
default_view_style,
|
||||
deserialize_view_style,
|
||||
UserDefaultConfig::load().get("view_style")
|
||||
UserDefaultConfig::read().get("view_style")
|
||||
);
|
||||
serde_field_string!(
|
||||
default_scroll_style,
|
||||
deserialize_scroll_style,
|
||||
UserDefaultConfig::load().get("scroll_style")
|
||||
UserDefaultConfig::read().get("scroll_style")
|
||||
);
|
||||
serde_field_string!(
|
||||
default_image_quality,
|
||||
deserialize_image_quality,
|
||||
UserDefaultConfig::load().get("image_quality")
|
||||
UserDefaultConfig::read().get("image_quality")
|
||||
);
|
||||
|
||||
fn default_custom_image_quality() -> Vec<i32> {
|
||||
let f: f64 = UserDefaultConfig::load()
|
||||
let f: f64 = UserDefaultConfig::read()
|
||||
.get("custom_image_quality")
|
||||
.parse()
|
||||
.unwrap_or(50.0);
|
||||
@ -1020,15 +1021,15 @@ impl PeerConfig {
|
||||
let mut mp: HashMap<String, String> = de::Deserialize::deserialize(deserializer)?;
|
||||
let mut key = "codec-preference";
|
||||
if !mp.contains_key(key) {
|
||||
mp.insert(key.to_owned(), UserDefaultConfig::load().get(key));
|
||||
mp.insert(key.to_owned(), UserDefaultConfig::read().get(key));
|
||||
}
|
||||
key = "custom-fps";
|
||||
if !mp.contains_key(key) {
|
||||
mp.insert(key.to_owned(), UserDefaultConfig::load().get(key));
|
||||
mp.insert(key.to_owned(), UserDefaultConfig::read().get(key));
|
||||
}
|
||||
key = "zoom-cursor";
|
||||
if !mp.contains_key(key) {
|
||||
mp.insert(key.to_owned(), UserDefaultConfig::load().get(key));
|
||||
mp.insert(key.to_owned(), UserDefaultConfig::read().get(key));
|
||||
}
|
||||
Ok(mp)
|
||||
}
|
||||
@ -1046,7 +1047,12 @@ serde_field_bool!(
|
||||
default_show_quality_monitor,
|
||||
"ShowQualityMonitor::default_show_quality_monitor"
|
||||
);
|
||||
serde_field_bool!(DisableAudio, "disable_audio", default_disable_audio, "DisableAudio::default_disable_audio");
|
||||
serde_field_bool!(
|
||||
DisableAudio,
|
||||
"disable_audio",
|
||||
default_disable_audio,
|
||||
"DisableAudio::default_disable_audio"
|
||||
);
|
||||
serde_field_bool!(
|
||||
EnableFileTransfer,
|
||||
"enable_file_transfer",
|
||||
@ -1065,9 +1071,19 @@ serde_field_bool!(
|
||||
default_lock_after_session_end,
|
||||
"LockAfterSessionEnd::default_lock_after_session_end"
|
||||
);
|
||||
serde_field_bool!(PrivacyMode, "privacy_mode", default_privacy_mode, "PrivacyMode::default_privacy_mode");
|
||||
serde_field_bool!(
|
||||
PrivacyMode,
|
||||
"privacy_mode",
|
||||
default_privacy_mode,
|
||||
"PrivacyMode::default_privacy_mode"
|
||||
);
|
||||
|
||||
serde_field_bool!(AllowSwapKey, "allow_swap_key", default_allow_swap_key, "AllowSwapKey::default_allow_swap_key");
|
||||
serde_field_bool!(
|
||||
AllowSwapKey,
|
||||
"allow_swap_key",
|
||||
default_allow_swap_key,
|
||||
"AllowSwapKey::default_allow_swap_key"
|
||||
);
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct LocalConfig {
|
||||
@ -1282,6 +1298,14 @@ pub struct UserDefaultConfig {
|
||||
}
|
||||
|
||||
impl UserDefaultConfig {
|
||||
pub fn read() -> UserDefaultConfig {
|
||||
let mut cfg = USER_DEFAULT_CONFIG.write().unwrap();
|
||||
if cfg.1.elapsed() > Duration::from_secs(1) {
|
||||
*cfg = (Self::load(), Instant::now());
|
||||
}
|
||||
cfg.0.clone()
|
||||
}
|
||||
|
||||
pub fn load() -> UserDefaultConfig {
|
||||
Config::load_::<UserDefaultConfig>("_default")
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ quest = "0.3"
|
||||
|
||||
[build-dependencies]
|
||||
target_build_utils = "0.3"
|
||||
bindgen = "0.59"
|
||||
bindgen = "0.64"
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
dbus = { version = "0.9", optional = true }
|
||||
|
@ -83,7 +83,7 @@ impl crate::TraitCapturer for Capturer {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Frame<'a>(quartz::Frame, PhantomData<&'a [u8]>);
|
||||
pub struct Frame<'a>(pub quartz::Frame, PhantomData<&'a [u8]>);
|
||||
|
||||
impl<'a> ops::Deref for Frame<'a> {
|
||||
type Target = [u8];
|
||||
|
@ -708,6 +708,7 @@ pub struct AudioHandler {
|
||||
audio_stream: Option<Box<dyn StreamTrait>>,
|
||||
channels: u16,
|
||||
latency_controller: Arc<Mutex<LatencyController>>,
|
||||
ignore_count: i32,
|
||||
}
|
||||
|
||||
impl AudioHandler {
|
||||
@ -810,7 +811,11 @@ impl AudioHandler {
|
||||
.check_audio(frame.timestamp)
|
||||
.not()
|
||||
{
|
||||
log::debug!("audio frame {} is ignored", frame.timestamp);
|
||||
self.ignore_count += 1;
|
||||
if self.ignore_count == 100 {
|
||||
self.ignore_count = 0;
|
||||
log::debug!("100 audio frames are ignored");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2233,7 +2238,7 @@ fn get_pk(pk: &[u8]) -> Option<[u8; 32]> {
|
||||
|
||||
#[inline]
|
||||
fn get_rs_pk(str_base64: &str) -> Option<sign::PublicKey> {
|
||||
if let Ok(pk) = base64::decode(str_base64) {
|
||||
if let Ok(pk) = crate::decode64(str_base64) {
|
||||
get_pk(&pk).map(|x| sign::PublicKey(x))
|
||||
} else {
|
||||
None
|
||||
|
@ -787,3 +787,15 @@ pub fn handle_url_scheme(url: String) {
|
||||
let _ = crate::run_me(vec![url]);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn encode64<T: AsRef<[u8]>>(input: T) -> String {
|
||||
#[allow(deprecated)]
|
||||
base64::encode(input)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn decode64<T: AsRef<[u8]>>(input: T) -> Result<Vec<u8>, base64::DecodeError> {
|
||||
#[allow(deprecated)]
|
||||
base64::decode(input)
|
||||
}
|
||||
|
@ -461,9 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Resolution", "Ανάλυση"),
|
||||
("No transfers in progress", "Δεν υπάρχει μεταφορά σε εξέλιξη"),
|
||||
("Set one-time password length", "Μέγεθος κωδικού μιας χρήσης"),
|
||||
("idd_driver_tip", ""),
|
||||
("confirm_idd_driver_tip", ""),
|
||||
("RDP Settings", ""),
|
||||
("idd_driver_tip", "Εγκαταστήστε το πρόγραμμα οδήγησης εικονικής οθόνης που χρησιμοποιείται όταν δεν έχετε φυσικές οθόνες."),
|
||||
("confirm_idd_driver_tip", "Είναι ενεργοποιημένη η επιλογή εγκατάστασης του προγράμματος οδήγησης εικονικής οθόνης. Λάβετε υπόψη ότι θα εγκατασταθεί ένα δοκιμαστικό πιστοποιητικό για το πρόγραμμα οδήγησης εικονικής οθόνης. Αυτό το πιστοποιητικό θα χρησιμοποιηθεί μόνο για την πιστοποίηση των προγραμμάτων οδήγησης του Rustdesk."),
|
||||
("RDP Settings", "Ρυθμίσεις RDP"),
|
||||
("Sort by", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -461,9 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Resolution", "Resolución"),
|
||||
("No transfers in progress", "No hay transferencias en curso"),
|
||||
("Set one-time password length", "Establecer contraseña de un solo uso"),
|
||||
("idd_driver_tip", ""),
|
||||
("confirm_idd_driver_tip", ""),
|
||||
("RDP Settings", ""),
|
||||
("idd_driver_tip", "Instalar controlador virtual de pantalla a usar cuando no hay pantalla física."),
|
||||
("confirm_idd_driver_tip", "La opción de instalar el controlador de pantalla virtual está marcada. Hay que tener en cuenta que se instalará un certificado de prueba para confirar en el controlador de pantalla. Este certificado solo se usará para confiar en controladores Rustdesk."),
|
||||
("RDP Settings", "Ajustes RDP"),
|
||||
("Sort by", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -461,9 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Resolution", "Разрешение"),
|
||||
("No transfers in progress", "Передача не осуществляется"),
|
||||
("Set one-time password length", "Установить длину одноразового пароля"),
|
||||
("idd_driver_tip", ""),
|
||||
("confirm_idd_driver_tip", ""),
|
||||
("RDP Settings", ""),
|
||||
("idd_driver_tip", "Установите драйвер виртуального дисплея, который используется при отсутствии физических дисплеев."),
|
||||
("confirm_idd_driver_tip", "Включена функция установки драйвера виртуального дисплея. Обратите внимание, что для доверия к драйверу будет установлен тестовый сертификат. Этот сертификат будет использоваться только для подтверждения доверия драйверам Rustdesk."),
|
||||
("RDP Settings", "Настройки RDP"),
|
||||
("Sort by", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
|
||||
use hbb_common::{bail, sodiumoxide::crypto::sign, ResultType};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
@ -18,7 +19,7 @@ fn get_license_from_string_(s: &str) -> ResultType<License> {
|
||||
12, 46, 129, 83, 17, 84, 193, 119, 197, 130, 103,
|
||||
];
|
||||
let pk = sign::PublicKey(*PK);
|
||||
let data = base64::decode_config(tmp, base64::URL_SAFE_NO_PAD)?;
|
||||
let data = URL_SAFE_NO_PAD.decode(tmp)?;
|
||||
if let Ok(lic) = serde_json::from_slice::<License>(&data) {
|
||||
return Ok(lic);
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
mod license;
|
||||
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
|
||||
use hbb_common::ResultType;
|
||||
use license::*;
|
||||
|
||||
fn gen_name(lic: &License) -> ResultType<String> {
|
||||
let tmp = serde_json::to_vec::<License>(lic)?;
|
||||
let tmp = base64::encode_config(tmp, base64::URL_SAFE_NO_PAD);
|
||||
let tmp = URL_SAFE_NO_PAD.encode(&tmp);
|
||||
let tmp: String = tmp.chars().rev().collect();
|
||||
Ok(tmp)
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
// https://github.com/codebytere/node-mac-permissions/blob/main/permissions.mm
|
||||
|
||||
extern "C" bool InputMonitoringAuthStatus(bool prompt) {
|
||||
#ifdef NO_InputMonitoringAuthStatus
|
||||
return true;
|
||||
#else
|
||||
if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_15) {
|
||||
IOHIDAccessType theType = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent);
|
||||
NSLog(@"IOHIDCheckAccess = %d, kIOHIDAccessTypeGranted = %d", theType, kIOHIDAccessTypeGranted);
|
||||
@ -36,6 +39,7 @@ extern "C" bool InputMonitoringAuthStatus(bool prompt) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" bool MacCheckAdminAuthorization() {
|
||||
|
@ -735,7 +735,7 @@ impl Connection {
|
||||
let url = self.server_audit_conn.clone();
|
||||
let mut v = v;
|
||||
v["id"] = json!(Config::get_id());
|
||||
v["uuid"] = json!(base64::encode(hbb_common::get_uuid()));
|
||||
v["uuid"] = json!(crate::encode64(hbb_common::get_uuid()));
|
||||
v["conn_id"] = json!(self.inner.id);
|
||||
tokio::spawn(async move {
|
||||
allow_err!(Self::post_audit_async(url, v).await);
|
||||
@ -765,7 +765,7 @@ impl Connection {
|
||||
info["files"] = json!(files);
|
||||
let v = json!({
|
||||
"id":json!(Config::get_id()),
|
||||
"uuid":json!(base64::encode(hbb_common::get_uuid())),
|
||||
"uuid":json!(crate::encode64(hbb_common::get_uuid())),
|
||||
"peer_id":json!(self.lr.my_id),
|
||||
"type": r#type as i8,
|
||||
"path":path,
|
||||
@ -788,7 +788,7 @@ impl Connection {
|
||||
}
|
||||
let mut v = Value::default();
|
||||
v["id"] = json!(Config::get_id());
|
||||
v["uuid"] = json!(base64::encode(hbb_common::get_uuid()));
|
||||
v["uuid"] = json!(crate::encode64(hbb_common::get_uuid()));
|
||||
v["typ"] = json!(typ as i8);
|
||||
v["from_remote"] = json!(from_remote);
|
||||
v["info"] = serde_json::Value::String(info.to_string());
|
||||
|
@ -848,7 +848,7 @@ pub fn elevate_portable(_id: i32) {
|
||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))]
|
||||
#[inline]
|
||||
pub fn handle_incoming_voice_call(id: i32, accept: bool) {
|
||||
if let Some(client) = CLIENTS.write().unwrap().get_mut(&id) {
|
||||
if let Some(client) = CLIENTS.read().unwrap().get(&id) {
|
||||
allow_err!(client.tx.send(Data::VoiceCallResponse(accept)));
|
||||
};
|
||||
}
|
||||
@ -856,7 +856,7 @@ pub fn handle_incoming_voice_call(id: i32, accept: bool) {
|
||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))]
|
||||
#[inline]
|
||||
pub fn close_voice_call(id: i32) {
|
||||
if let Some(client) = CLIENTS.write().unwrap().get_mut(&id) {
|
||||
if let Some(client) = CLIENTS.read().unwrap().get(&id) {
|
||||
allow_err!(client.tx.send(Data::CloseVoiceCall("".to_owned())));
|
||||
};
|
||||
}
|
||||
|
@ -605,7 +605,7 @@ pub fn remove_discovered(id: String) {
|
||||
|
||||
#[inline]
|
||||
pub fn get_uuid() -> String {
|
||||
base64::encode(hbb_common::get_uuid())
|
||||
crate::encode64(hbb_common::get_uuid())
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))]
|
||||
@ -876,7 +876,7 @@ pub async fn change_id_shared(id: String, old_id: String) -> &'static str {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
let uuid = machine_uid::get().unwrap_or("".to_owned());
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let uuid = base64::encode(hbb_common::get_uuid());
|
||||
let uuid = crate::encode64(hbb_common::get_uuid());
|
||||
|
||||
if uuid.is_empty() {
|
||||
log::error!("Failed to change id, uuid is_empty");
|
||||
|
Loading…
x
Reference in New Issue
Block a user