2022-08-01 20:42:30 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
use hbb_common ::password_security ;
2022-05-26 18:11:00 +08:00
use hbb_common ::{
allow_err ,
2023-06-25 15:37:39 +08:00
bytes ::Bytes ,
2024-07-24 17:20:58 +08:00
config ::{
self , keys ::* , option2bool , Config , LocalConfig , PeerConfig , CONNECT_TIMEOUT ,
RENDEZVOUS_PORT ,
} ,
2023-10-08 21:44:54 +08:00
directories_next ,
2023-06-24 21:09:45 +08:00
futures ::future ::join_all ,
2023-10-08 21:44:54 +08:00
log ,
2023-06-24 21:09:45 +08:00
rendezvous_proto ::* ,
2023-10-08 21:44:54 +08:00
tokio ,
2023-06-24 21:09:45 +08:00
} ;
2023-03-27 19:13:29 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
use hbb_common ::{
sleep ,
tokio ::{ sync ::mpsc , time } ,
2022-11-10 21:25:12 +08:00
} ;
2023-06-24 21:09:45 +08:00
use serde_derive ::Serialize ;
2023-10-08 21:44:54 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
use std ::process ::Child ;
2023-06-24 21:09:45 +08:00
use std ::{
collections ::HashMap ,
2024-04-28 21:08:49 +08:00
sync ::atomic ::{ AtomicUsize , Ordering } ,
2023-06-24 21:09:45 +08:00
sync ::{ Arc , Mutex } ,
2022-05-26 18:11:00 +08:00
} ;
2022-07-18 18:20:00 +08:00
2023-04-19 14:39:22 +08:00
use crate ::common ::SOFTWARE_UPDATE_URL ;
2022-11-09 15:04:24 +08:00
#[ cfg(feature = " flutter " ) ]
use crate ::hbbs_http ::account ;
2023-04-17 19:26:39 +08:00
#[ cfg(not(any(target_os = " ios " ))) ]
use crate ::ipc ;
2022-05-26 18:11:00 +08:00
type Message = RendezvousMessage ;
2023-10-08 21:44:54 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-11-10 21:25:12 +08:00
pub type Children = Arc < Mutex < ( bool , HashMap < ( String , String ) , Child > ) > > ;
2023-06-24 21:09:45 +08:00
#[ derive(Clone, Debug, Serialize) ]
pub struct UiStatus {
pub status_num : i32 ,
#[ cfg(not(feature = " flutter " )) ]
pub key_confirmed : bool ,
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
pub mouse_time : i64 ,
#[ cfg(not(feature = " flutter " )) ]
pub id : String ,
}
2022-05-26 18:11:00 +08:00
2023-08-09 20:27:52 +08:00
#[ derive(Debug, Clone, Serialize) ]
pub struct LoginDeviceInfo {
pub os : String ,
pub r#type : String ,
pub name : String ,
}
2022-05-26 18:11:00 +08:00
lazy_static ::lazy_static! {
2023-06-24 21:09:45 +08:00
static ref UI_STATUS : Arc < Mutex < UiStatus > > = Arc ::new ( Mutex ::new ( UiStatus {
status_num : 0 ,
#[ cfg(not(feature = " flutter " )) ]
key_confirmed : false ,
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
mouse_time : 0 ,
#[ cfg(not(feature = " flutter " )) ]
id : " " . to_owned ( ) ,
} ) ) ;
2022-11-10 21:25:12 +08:00
static ref ASYNC_JOB_STATUS : Arc < Mutex < String > > = Default ::default ( ) ;
2024-04-25 11:46:21 +08:00
static ref ASYNC_HTTP_STATUS : Arc < Mutex < HashMap < String , String > > > = Arc ::new ( Mutex ::new ( HashMap ::new ( ) ) ) ;
2022-11-10 21:25:12 +08:00
static ref TEMPORARY_PASSWD : Arc < Mutex < String > > = Arc ::new ( Mutex ::new ( " " . to_owned ( ) ) ) ;
2022-05-26 18:11:00 +08:00
}
2024-04-28 21:08:49 +08:00
pub static VIDEO_CONN_COUNT : AtomicUsize = AtomicUsize ::new ( 0 ) ;
2022-08-03 21:51:35 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
lazy_static ::lazy_static! {
2023-06-24 16:13:20 +08:00
static ref OPTION_SYNCED : Arc < Mutex < bool > > = Default ::default ( ) ;
static ref OPTIONS : Arc < Mutex < HashMap < String , String > > > = Arc ::new ( Mutex ::new ( Config ::get_options ( ) ) ) ;
2022-08-03 21:51:35 +08:00
pub static ref SENDER : Mutex < mpsc ::UnboundedSender < ipc ::Data > > = Mutex ::new ( check_connect_status ( true ) ) ;
2023-08-01 22:19:38 +08:00
static ref CHILDREN : Children = Default ::default ( ) ;
2022-08-03 21:51:35 +08:00
}
2023-06-25 13:14:21 +08:00
const INIT_ASYNC_JOB_STATUS : & str = " " ;
2022-11-10 21:25:12 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " flutter " )) ]
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_id ( ) -> String {
2022-08-03 21:51:35 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
return Config ::get_id ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return ipc ::get_id ( ) ;
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn goto_install ( ) {
allow_err! ( crate ::run_me ( vec! [ " --install " ] ) ) ;
2023-06-07 14:25:34 +08:00
std ::process ::exit ( 0 ) ;
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-10-26 06:40:22 -07:00
pub fn install_me ( _options : String , _path : String , _silent : bool , _debug : bool ) {
2022-05-26 18:11:00 +08:00
#[ cfg(windows) ]
std ::thread ::spawn ( move | | {
2022-07-18 18:20:00 +08:00
allow_err! ( crate ::platform ::windows ::install_me (
2022-10-26 06:40:22 -07:00
& _options , _path , _silent , _debug
2022-07-18 18:20:00 +08:00
) ) ;
2022-05-26 18:11:00 +08:00
std ::process ::exit ( 0 ) ;
} ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn update_me ( _path : String ) {
2023-06-05 20:27:48 +08:00
goto_install ( ) ;
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn run_without_install ( ) {
crate ::run_me ( vec! [ " --noinstall " ] ) . ok ( ) ;
std ::process ::exit ( 0 ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn show_run_without_install ( ) -> bool {
let mut it = std ::env ::args ( ) ;
if let Some ( tmp ) = it . next ( ) {
if crate ::is_setup ( & tmp ) {
return it . next ( ) = = None ;
}
}
false
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_license ( ) -> String {
#[ cfg(windows) ]
2023-07-19 14:45:11 +08:00
if let Ok ( lic ) = crate ::platform ::windows ::get_license_from_exe_name ( ) {
2022-10-31 14:59:57 +08:00
#[ cfg(feature = " flutter " ) ]
2024-04-02 11:44:27 +08:00
return format! ( " Key: {} \n Host: {} \n API: {} " , lic . key , lic . host , lic . api ) ;
2022-10-31 14:59:57 +08:00
// default license format is html formed (sciter)
2022-11-10 21:25:12 +08:00
#[ cfg(not(feature = " flutter " )) ]
2022-05-26 18:11:00 +08:00
return format! (
2024-04-02 11:44:27 +08:00
" <br /> Key: {} <br /> Host: {} API: {} " ,
2022-05-26 18:11:00 +08:00
lic . key , lic . host , lic . api
) ;
}
Default ::default ( )
}
2024-01-19 15:35:58 +08:00
#[ inline ]
pub fn refresh_options ( ) {
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
{
* OPTIONS . lock ( ) . unwrap ( ) = Config ::get_options ( ) ;
}
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2023-06-24 16:13:20 +08:00
pub fn get_option < T : AsRef < str > > ( key : T ) -> String {
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
{
2023-06-24 21:09:45 +08:00
let map = OPTIONS . lock ( ) . unwrap ( ) ;
if let Some ( v ) = map . get ( key . as_ref ( ) ) {
v . to_owned ( )
} else {
" " . to_owned ( )
}
2023-06-24 16:13:20 +08:00
}
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
{
Config ::get_option ( key . as_ref ( ) )
}
2022-05-26 18:11:00 +08:00
}
2024-05-28 16:42:30 +08:00
#[ inline ]
#[ cfg(target_os = " macos " ) ]
pub fn use_texture_render ( ) -> bool {
hwcodec, only process that start ipc server start check process (#8325)
check process send config to ipc server, other process get config from ipc server. Process will save config to toml, and the toml will be used if the config is none.
when start check process: ipc server process start or option changed
from disable to enable
when get config: main window start or option changed from disable to
enable, start_video_audio_threads.
Only windows implements signature, which is used to mark whether the gpu software and hardware information changes. After reboot, the signature doesn't change. https://asawicki.info/news_1773_how_to_programmatically_check_graphics_driver_version, use dxgi way to get software version, it's not consistent with the visible driver version, after updating intel driver with small version change, the signature doesn't change. Linux doesn't use toml file.
Signed-off-by: 21pages <sunboeasy@gmail.com>
2024-06-12 20:40:35 +08:00
cfg! ( feature = " flutter " ) & & LocalConfig ::get_option ( config ::keys ::OPTION_TEXTURE_RENDER ) = = " Y "
2024-05-28 16:42:30 +08:00
}
#[ inline ]
#[ cfg(any(target_os = " windows " , target_os = " linux " )) ]
pub fn use_texture_render ( ) -> bool {
hwcodec, only process that start ipc server start check process (#8325)
check process send config to ipc server, other process get config from ipc server. Process will save config to toml, and the toml will be used if the config is none.
when start check process: ipc server process start or option changed
from disable to enable
when get config: main window start or option changed from disable to
enable, start_video_audio_threads.
Only windows implements signature, which is used to mark whether the gpu software and hardware information changes. After reboot, the signature doesn't change. https://asawicki.info/news_1773_how_to_programmatically_check_graphics_driver_version, use dxgi way to get software version, it's not consistent with the visible driver version, after updating intel driver with small version change, the signature doesn't change. Linux doesn't use toml file.
Signed-off-by: 21pages <sunboeasy@gmail.com>
2024-06-12 20:40:35 +08:00
cfg! ( feature = " flutter " ) & & LocalConfig ::get_option ( config ::keys ::OPTION_TEXTURE_RENDER ) ! = " N "
2024-05-28 16:42:30 +08:00
}
#[ inline ]
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
pub fn use_texture_render ( ) -> bool {
false
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_local_option ( key : String ) -> String {
LocalConfig ::get_option ( & key )
}
2024-03-10 12:48:00 +08:00
#[ inline ]
pub fn get_hard_option ( key : String ) -> String {
config ::HARD_SETTINGS
. read ( )
. unwrap ( )
. get ( & key )
. cloned ( )
. unwrap_or_default ( )
}
2024-07-19 23:55:52 +08:00
#[ inline ]
2024-08-07 01:08:36 +08:00
pub fn get_builtin_option ( key : & str ) -> String {
config ::BUILTIN_SETTINGS
2024-07-19 23:55:52 +08:00
. read ( )
. unwrap ( )
. get ( key )
. cloned ( )
. unwrap_or_default ( )
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn set_local_option ( key : String , value : String ) {
LocalConfig ::set_option ( key , value ) ;
}
2022-11-10 07:26:09 -08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " flutter " )) ]
2022-11-10 21:25:12 +08:00
#[ inline ]
2023-08-10 22:27:35 +08:00
pub fn get_local_flutter_option ( key : String ) -> String {
LocalConfig ::get_flutter_option ( & key )
2022-11-10 21:25:12 +08:00
}
2022-11-10 07:26:09 -08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " flutter " )) ]
2022-11-10 21:25:12 +08:00
#[ inline ]
2023-08-10 22:27:35 +08:00
pub fn set_local_flutter_option ( key : String , value : String ) {
LocalConfig ::set_flutter_option ( key , value ) ;
2022-11-10 21:25:12 +08:00
}
2022-12-29 14:28:15 +08:00
#[ cfg(feature = " flutter " ) ]
2022-12-27 16:45:13 +08:00
#[ inline ]
pub fn get_kb_layout_type ( ) -> String {
LocalConfig ::get_kb_layout_type ( )
}
2022-12-29 14:28:15 +08:00
#[ cfg(feature = " flutter " ) ]
2022-12-27 16:45:13 +08:00
#[ inline ]
pub fn set_kb_layout_type ( kb_layout_type : String ) {
LocalConfig ::set_kb_layout_type ( kb_layout_type ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn peer_has_password ( id : String ) -> bool {
! PeerConfig ::load ( & id ) . password . is_empty ( )
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn forget_password ( id : String ) {
let mut c = PeerConfig ::load ( & id ) ;
c . password . clear ( ) ;
c . store ( & id ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_peer_option ( id : String , name : String ) -> String {
let c = PeerConfig ::load ( & id ) ;
c . options . get ( & name ) . unwrap_or ( & " " . to_owned ( ) ) . to_owned ( )
2023-08-08 18:14:01 +08:00
}
#[ inline ]
#[ cfg(feature = " flutter " ) ]
2023-08-10 22:27:35 +08:00
pub fn get_peer_flutter_option ( id : String , name : String ) -> String {
2023-08-08 18:14:01 +08:00
let c = PeerConfig ::load ( & id ) ;
c . ui_flutter . get ( & name ) . unwrap_or ( & " " . to_owned ( ) ) . to_owned ( )
2022-05-26 18:11:00 +08:00
}
2023-08-10 19:48:26 +08:00
#[ inline ]
#[ cfg(feature = " flutter " ) ]
2023-08-10 22:27:35 +08:00
pub fn set_peer_flutter_option ( id : String , name : String , value : String ) {
2023-08-10 19:48:26 +08:00
let mut c = PeerConfig ::load ( & id ) ;
if value . is_empty ( ) {
c . ui_flutter . remove ( & name ) ;
} else {
c . ui_flutter . insert ( name , value ) ;
}
c . store ( & id ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn set_peer_option ( id : String , name : String , value : String ) {
let mut c = PeerConfig ::load ( & id ) ;
if value . is_empty ( ) {
c . options . remove ( & name ) ;
} else {
c . options . insert ( name , value ) ;
}
c . store ( & id ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-07-18 18:20:00 +08:00
pub fn get_options ( ) -> String {
2023-06-24 16:13:20 +08:00
let options = {
2023-06-24 21:09:45 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
{
OPTIONS . lock ( ) . unwrap ( )
}
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
{
Config ::get_options ( )
}
2023-06-24 16:13:20 +08:00
} ;
2022-07-18 18:20:00 +08:00
let mut m = serde_json ::Map ::new ( ) ;
2022-05-26 18:11:00 +08:00
for ( k , v ) in options . iter ( ) {
2022-07-18 18:20:00 +08:00
m . insert ( k . into ( ) , v . to_owned ( ) . into ( ) ) ;
2022-05-26 18:11:00 +08:00
}
2023-07-22 14:16:41 +08:00
serde_json ::to_string ( & m ) . unwrap_or_default ( )
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2024-04-28 14:22:21 +08:00
pub fn test_if_valid_server ( host : String , test_with_proxy : bool ) -> String {
hbb_common ::socket_client ::test_if_valid_server ( & host , test_with_proxy )
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-11-10 21:25:12 +08:00
#[ cfg(feature = " flutter " ) ]
2022-11-13 18:11:13 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-05-26 18:11:00 +08:00
pub fn get_sound_inputs ( ) -> Vec < String > {
let mut a = Vec ::new ( ) ;
2022-09-08 21:40:43 +08:00
#[ cfg(not(target_os = " linux " )) ]
2022-05-26 18:11:00 +08:00
{
fn get_sound_inputs_ ( ) -> Vec < String > {
let mut out = Vec ::new ( ) ;
use cpal ::traits ::{ DeviceTrait , HostTrait } ;
let host = cpal ::default_host ( ) ;
if let Ok ( devices ) = host . devices ( ) {
for device in devices {
if device . default_input_config ( ) . is_err ( ) {
continue ;
}
if let Ok ( name ) = device . name ( ) {
out . push ( name ) ;
}
}
}
out
}
let inputs = Arc ::new ( Mutex ::new ( Vec ::new ( ) ) ) ;
let cloned = inputs . clone ( ) ;
// can not call below in UI thread, because conflict with sciter sound com initialization
std ::thread ::spawn ( move | | * cloned . lock ( ) . unwrap ( ) = get_sound_inputs_ ( ) )
. join ( )
. ok ( ) ;
for name in inputs . lock ( ) . unwrap ( ) . drain ( .. ) {
a . push ( name ) ;
}
}
2022-09-13 22:37:16 +08:00
#[ cfg(target_os = " linux " ) ]
2022-05-26 18:11:00 +08:00
{
let inputs : Vec < String > = crate ::platform ::linux ::get_pa_sources ( )
. drain ( .. )
. map ( | x | x . 1 )
. collect ( ) ;
for name in inputs {
a . push ( name ) ;
}
}
a
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn set_options ( m : HashMap < String , String > ) {
2022-08-03 21:51:35 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2023-06-24 16:13:20 +08:00
{
2023-06-24 21:09:45 +08:00
* OPTIONS . lock ( ) . unwrap ( ) = m . clone ( ) ;
ipc ::set_options ( m ) . ok ( ) ;
2023-06-24 16:13:20 +08:00
}
2022-08-08 17:53:51 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
Config ::set_options ( m ) ;
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn set_option ( key : String , value : String ) {
2022-08-08 17:53:51 +08:00
if & key = = " stop-service " {
2023-06-05 20:27:48 +08:00
#[ cfg(target_os = " macos " ) ]
{
let is_stop = value = = " Y " ;
2024-03-27 00:38:13 +08:00
if is_stop & & crate ::platform ::uninstall_service ( true , false ) {
2023-06-05 20:27:48 +08:00
return ;
}
}
2023-06-07 23:08:50 +08:00
#[ cfg(any(target_os = " windows " , target_os = " linux " )) ]
2023-06-05 20:27:48 +08:00
{
if crate ::platform ::is_installed ( ) {
if value = = " Y " {
2024-03-27 00:38:13 +08:00
if crate ::platform ::uninstall_service ( true , false ) {
2023-06-10 21:30:53 +08:00
return ;
2023-06-07 23:08:50 +08:00
}
2023-06-05 20:27:48 +08:00
} else {
2023-06-07 23:08:50 +08:00
if crate ::platform ::install_service ( ) {
return ;
}
2023-06-05 20:27:48 +08:00
}
return ;
}
2022-08-01 20:42:30 +08:00
}
2024-05-07 16:18:48 +08:00
} else if & key = = " audio-input " {
2024-05-07 16:53:57 +08:00
#[ cfg(not(target_os = " ios " )) ]
2024-05-07 16:18:48 +08:00
crate ::audio_service ::restart ( ) ;
2022-05-26 18:11:00 +08:00
}
2023-06-24 16:13:20 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
{
2023-06-24 21:09:45 +08:00
let mut options = OPTIONS . lock ( ) . unwrap ( ) ;
if value . is_empty ( ) {
options . remove ( & key ) ;
} else {
options . insert ( key . clone ( ) , value . clone ( ) ) ;
}
ipc ::set_options ( options . clone ( ) ) . ok ( ) ;
2023-06-24 16:13:20 +08:00
}
2022-08-08 17:53:51 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
Config ::set_option ( key , value ) ;
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn install_path ( ) -> String {
#[ cfg(windows) ]
return crate ::platform ::windows ::get_install_info ( ) . 1 ;
#[ cfg(not(windows)) ]
return " " . to_owned ( ) ;
}
2024-08-08 22:07:06 +08:00
#[ inline ]
pub fn install_options ( ) -> String {
#[ cfg(windows) ]
return crate ::platform ::windows ::get_install_options ( ) ;
#[ cfg(not(windows)) ]
return " {} " . to_owned ( ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_socks ( ) -> Vec < String > {
2022-08-03 21:51:35 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2024-07-15 18:53:14 +08:00
let s = ipc ::get_socks ( ) ;
#[ cfg(target_os = " android " ) ]
let s = Config ::get_socks ( ) ;
#[ cfg(target_os = " ios " ) ]
let s : Option < config ::Socks5Server > = None ;
match s {
None = > Vec ::new ( ) ,
Some ( s ) = > {
let mut v = Vec ::new ( ) ;
v . push ( s . proxy ) ;
v . push ( s . username ) ;
v . push ( s . password ) ;
v
2022-05-26 18:11:00 +08:00
}
}
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn set_socks ( proxy : String , username : String , password : String ) {
2024-07-15 18:53:14 +08:00
let socks = config ::Socks5Server {
2022-05-26 18:11:00 +08:00
proxy ,
username ,
password ,
2024-07-15 18:53:14 +08:00
} ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
ipc ::set_socks ( socks ) . ok ( ) ;
#[ cfg(target_os = " android " ) ]
{
if socks . proxy . is_empty ( ) {
Config ::set_socks ( None ) ;
} else {
Config ::set_socks ( Some ( socks ) ) ;
}
crate ::common ::test_nat_type ( ) ;
crate ::RendezvousMediator ::restart ( ) ;
log ::info! ( " socks updated " ) ;
}
2022-05-26 18:11:00 +08:00
}
2024-04-25 11:46:21 +08:00
#[ inline ]
pub fn get_proxy_status ( ) -> bool {
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return ipc ::get_proxy_status ( ) ;
2024-04-28 21:08:49 +08:00
2024-04-25 11:46:21 +08:00
// Currently, only the desktop version has proxy settings.
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
return false ;
}
2022-11-10 21:25:12 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn is_installed ( ) -> bool {
2022-11-10 21:25:12 +08:00
crate ::platform ::is_installed ( )
}
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
#[ inline ]
2022-11-10 10:27:13 +08:00
pub fn is_installed ( ) -> bool {
2022-09-23 16:56:28 +08:00
false
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn is_share_rdp ( ) -> bool {
#[ cfg(windows) ]
return crate ::platform ::windows ::is_share_rdp ( ) ;
#[ cfg(not(windows)) ]
return false ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn set_share_rdp ( _enable : bool ) {
#[ cfg(windows) ]
crate ::platform ::windows ::set_share_rdp ( _enable ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn is_installed_lower_version ( ) -> bool {
#[ cfg(not(windows)) ]
return false ;
#[ cfg(windows) ]
{
2023-06-05 20:27:48 +08:00
let b = crate ::platform ::windows ::get_reg ( " BuildDate " ) ;
return crate ::BUILD_DATE . cmp ( & b ) . is_gt ( ) ;
2022-05-26 18:11:00 +08:00
}
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2023-06-24 21:09:45 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-05-26 18:11:00 +08:00
pub fn get_mouse_time ( ) -> f64 {
2023-06-24 21:09:45 +08:00
UI_STATUS . lock ( ) . unwrap ( ) . mouse_time as f64
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn check_mouse_time ( ) {
2023-06-23 12:49:36 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-09-07 18:57:49 +08:00
{
2022-09-05 20:05:23 +08:00
let sender = SENDER . lock ( ) . unwrap ( ) ;
allow_err! ( sender . send ( ipc ::Data ::MouseMoveTime ( 0 ) ) ) ;
}
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2023-06-24 21:09:45 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
pub fn get_connect_status ( ) -> UiStatus {
UI_STATUS . lock ( ) . unwrap ( ) . clone ( )
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-08-01 20:42:30 +08:00
pub fn temporary_password ( ) -> String {
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
return password_security ::temporary_password ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return TEMPORARY_PASSWD . lock ( ) . unwrap ( ) . clone ( ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-08-01 14:33:08 +08:00
pub fn update_temporary_password ( ) {
2022-08-01 20:42:30 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
password_security ::update_temporary_password ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-08-01 14:33:08 +08:00
allow_err! ( ipc ::update_temporary_password ( ) ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-08-01 14:33:08 +08:00
pub fn permanent_password ( ) -> String {
2022-08-01 20:42:30 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
return Config ::get_permanent_password ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return ipc ::get_permanent_password ( ) ;
2022-08-01 14:33:08 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-08-01 20:42:30 +08:00
pub fn set_permanent_password ( password : String ) {
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
Config ::set_permanent_password ( & password ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
allow_err! ( ipc ::set_permanent_password ( password ) ) ;
2022-08-01 14:33:08 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_peer ( id : String ) -> PeerConfig {
PeerConfig ::load ( & id )
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_fav ( ) -> Vec < String > {
LocalConfig ::get_fav ( )
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn store_fav ( fav : Vec < String > ) {
LocalConfig ::set_fav ( fav ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn is_process_trusted ( _prompt : bool ) -> bool {
#[ cfg(target_os = " macos " ) ]
return crate ::platform ::macos ::is_process_trusted ( _prompt ) ;
#[ cfg(not(target_os = " macos " )) ]
return true ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn is_can_screen_recording ( _prompt : bool ) -> bool {
#[ cfg(target_os = " macos " ) ]
return crate ::platform ::macos ::is_can_screen_recording ( _prompt ) ;
#[ cfg(not(target_os = " macos " )) ]
return true ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn is_installed_daemon ( _prompt : bool ) -> bool {
#[ cfg(target_os = " macos " ) ]
return crate ::platform ::macos ::is_installed_daemon ( _prompt ) ;
#[ cfg(not(target_os = " macos " )) ]
return true ;
}
2023-01-06 12:20:26 +08:00
#[ inline ]
2023-01-20 21:03:30 +08:00
#[ cfg(feature = " flutter " ) ]
2023-01-06 12:20:26 +08:00
pub fn is_can_input_monitoring ( _prompt : bool ) -> bool {
#[ cfg(target_os = " macos " ) ]
return crate ::platform ::macos ::is_can_input_monitoring ( _prompt ) ;
#[ cfg(not(target_os = " macos " )) ]
return true ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_error ( ) -> String {
2022-06-27 12:09:27 +08:00
#[ cfg(not(any(feature = " cli " ))) ]
2022-05-26 18:11:00 +08:00
#[ cfg(target_os = " linux " ) ]
{
let dtype = crate ::platform ::linux ::get_display_server ( ) ;
2023-04-19 14:39:22 +08:00
if crate ::platform ::linux ::DISPLAY_SERVER_WAYLAND = = dtype {
2022-10-11 20:36:19 -07:00
return crate ::server ::wayland ::common_get_error ( ) ;
2022-05-26 18:11:00 +08:00
}
2023-03-30 18:16:48 +08:00
if dtype ! = crate ::platform ::linux ::DISPLAY_SERVER_X11 {
2022-05-26 18:11:00 +08:00
return format! (
" {} {}, {} " ,
2023-03-08 11:44:41 +08:00
crate ::client ::translate ( " Unsupported display server " . to_owned ( ) ) ,
2022-05-26 18:11:00 +08:00
dtype ,
2023-02-10 17:38:08 +08:00
crate ::client ::translate ( " x11 expected " . to_owned ( ) ) ,
2022-05-26 18:11:00 +08:00
) ;
}
}
return " " . to_owned ( ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn is_login_wayland ( ) -> bool {
#[ cfg(target_os = " linux " ) ]
return crate ::platform ::linux ::is_login_wayland ( ) ;
#[ cfg(not(target_os = " linux " )) ]
return false ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn current_is_wayland ( ) -> bool {
#[ cfg(target_os = " linux " ) ]
return crate ::platform ::linux ::current_is_wayland ( ) ;
#[ cfg(not(target_os = " linux " )) ]
return false ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_new_version ( ) -> String {
2023-09-09 19:24:38 +08:00
( * SOFTWARE_UPDATE_URL
. lock ( )
. unwrap ( )
. rsplit ( '/' )
. next ( )
. unwrap_or ( " " ) )
. to_string ( )
2022-05-26 18:11:00 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_version ( ) -> String {
crate ::VERSION . to_owned ( )
}
2022-11-10 21:25:12 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " flutter " )) ]
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_app_name ( ) -> String {
crate ::get_app_name ( )
}
2023-02-10 17:09:31 +08:00
#[ cfg(windows) ]
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn create_shortcut ( _id : String ) {
crate ::platform ::windows ::create_shortcut ( & _id ) . ok ( ) ;
}
2022-11-10 21:25:12 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " flutter " )) ]
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn discover ( ) {
std ::thread ::spawn ( move | | {
2022-08-02 13:10:09 +08:00
allow_err! ( crate ::lan ::discover ( ) ) ;
2022-05-26 18:11:00 +08:00
} ) ;
}
2022-12-07 16:30:44 +08:00
#[ cfg(feature = " flutter " ) ]
2022-11-28 18:16:29 +08:00
pub fn peer_to_map ( id : String , p : PeerConfig ) -> HashMap < & 'static str , String > {
2023-08-20 11:24:34 +08:00
use hbb_common ::sodiumoxide ::base64 ;
2022-11-28 18:16:29 +08:00
HashMap ::< & str , String > ::from_iter ( [
( " id " , id ) ,
( " username " , p . info . username . clone ( ) ) ,
( " hostname " , p . info . hostname . clone ( ) ) ,
( " platform " , p . info . platform . clone ( ) ) ,
(
" alias " ,
p . options . get ( " alias " ) . unwrap_or ( & " " . to_owned ( ) ) . to_owned ( ) ,
) ,
2023-08-20 11:24:34 +08:00
(
" hash " ,
base64 ::encode ( p . password , base64 ::Variant ::Original ) ,
) ,
2022-11-28 18:16:29 +08:00
] )
}
2023-08-16 08:59:50 +08:00
#[ cfg(feature = " flutter " ) ]
pub fn peer_exists ( id : & str ) -> bool {
PeerConfig ::exists ( id )
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-09-21 21:20:19 +08:00
pub fn get_lan_peers ( ) -> Vec < HashMap < & 'static str , String > > {
2022-08-24 23:22:50 +08:00
config ::LanPeers ::load ( )
2022-08-02 13:10:09 +08:00
. peers
. iter ( )
. map ( | peer | {
2022-09-21 21:20:19 +08:00
HashMap ::< & str , String > ::from_iter ( [
( " id " , peer . id . clone ( ) ) ,
( " username " , peer . username . clone ( ) ) ,
( " hostname " , peer . hostname . clone ( ) ) ,
( " platform " , peer . platform . clone ( ) ) ,
] )
2022-08-02 13:10:09 +08:00
} )
2022-08-24 23:22:50 +08:00
. collect ( )
2022-05-26 18:11:00 +08:00
}
2023-02-24 13:13:51 +08:00
#[ inline ]
pub fn remove_discovered ( id : String ) {
let mut peers = config ::LanPeers ::load ( ) . peers ;
peers . retain ( | x | x . id ! = id ) ;
config ::LanPeers ::store ( & peers ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_uuid ( ) -> String {
2023-03-09 17:22:14 +08:00
crate ::encode64 ( hbb_common ::get_uuid ( ) )
2022-05-26 18:11:00 +08:00
}
2023-06-25 13:14:21 +08:00
#[ inline ]
pub fn get_init_async_job_status ( ) -> String {
INIT_ASYNC_JOB_STATUS . to_string ( )
}
#[ inline ]
pub fn reset_async_job_status ( ) {
* ASYNC_JOB_STATUS . lock ( ) . unwrap ( ) = get_init_async_job_status ( ) ;
}
2022-11-10 21:25:12 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " flutter " )) ]
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn change_id ( id : String ) {
2023-06-25 13:14:21 +08:00
reset_async_job_status ( ) ;
2022-05-26 18:11:00 +08:00
let old_id = get_id ( ) ;
std ::thread ::spawn ( move | | {
2023-06-25 15:37:39 +08:00
change_id_shared ( id , old_id ) ;
2022-05-26 18:11:00 +08:00
} ) ;
}
2024-04-25 11:46:21 +08:00
#[ inline ]
pub fn http_request ( url : String , method : String , body : Option < String > , header : String ) {
// Respond to concurrent requests for resources
let current_request = ASYNC_HTTP_STATUS . clone ( ) ;
2024-04-28 21:08:49 +08:00
current_request
. lock ( )
. unwrap ( )
. insert ( url . clone ( ) , " " . to_owned ( ) ) ;
2024-04-25 11:46:21 +08:00
std ::thread ::spawn ( move | | {
2024-04-28 21:08:49 +08:00
let res = match crate ::http_request_sync ( url . clone ( ) , method , body , header ) {
Err ( err ) = > {
log ::error! ( " {} " , err ) ;
err . to_string ( )
}
Ok ( text ) = > text ,
} ;
current_request . lock ( ) . unwrap ( ) . insert ( url , res ) ;
2024-04-25 11:46:21 +08:00
} ) ;
}
2024-08-07 01:08:36 +08:00
2024-04-25 11:46:21 +08:00
#[ inline ]
pub fn get_async_http_status ( url : String ) -> Option < String > {
match ASYNC_HTTP_STATUS . lock ( ) . unwrap ( ) . get ( & url ) {
2024-04-28 21:08:49 +08:00
None = > None ,
Some ( _str ) = > Some ( _str . to_string ( ) ) ,
2024-04-25 11:46:21 +08:00
}
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn post_request ( url : String , body : String , header : String ) {
* ASYNC_JOB_STATUS . lock ( ) . unwrap ( ) = " " . to_owned ( ) ;
std ::thread ::spawn ( move | | {
* ASYNC_JOB_STATUS . lock ( ) . unwrap ( ) = match crate ::post_request_sync ( url , body , & header ) {
Err ( err ) = > err . to_string ( ) ,
Ok ( text ) = > text ,
} ;
} ) ;
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_async_job_status ( ) -> String {
ASYNC_JOB_STATUS . lock ( ) . unwrap ( ) . clone ( )
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-08-13 12:43:35 +08:00
pub fn get_langs ( ) -> String {
2023-03-03 11:36:12 +08:00
use serde_json ::json ;
let mut x : Vec < ( & str , String ) > = crate ::lang ::LANGS
. iter ( )
2023-03-03 11:49:02 +08:00
. map ( | a | ( a . 0 , format! ( " {} ( {} ) " , a . 1 , a . 0 ) ) )
2023-03-03 11:36:12 +08:00
. collect ( ) ;
x . sort_by ( | a , b | a . 0. cmp ( b . 0 ) ) ;
json! ( x ) . to_string ( )
2022-08-13 12:43:35 +08:00
}
2022-09-15 17:31:28 +08:00
#[ inline ]
2024-05-08 17:04:53 +08:00
pub fn video_save_directory ( root : bool ) -> String {
2022-10-12 16:06:15 +08:00
let appname = crate ::get_app_name ( ) ;
2023-03-10 21:32:43 +08:00
// ui process can show it correctly Once vidoe process created it.
2023-03-10 16:41:00 +08:00
let try_create = | path : & std ::path ::Path | {
if ! path . exists ( ) {
2023-03-10 21:32:43 +08:00
std ::fs ::create_dir_all ( path ) . ok ( ) ;
}
if path . exists ( ) {
path . to_string_lossy ( ) . to_string ( )
} else {
" " . to_string ( )
2023-03-10 16:41:00 +08:00
}
} ;
2022-10-25 10:16:11 +09:00
2024-05-08 17:04:53 +08:00
if root {
// Currently, only installed windows run as root
#[ cfg(windows) ]
{
let drive = std ::env ::var ( " SystemDrive " ) . unwrap_or ( " C: " . to_owned ( ) ) ;
let dir =
std ::path ::PathBuf ::from ( format! ( " {drive} \\ ProgramData \\ RustDesk \\ recording " , ) ) ;
return dir . to_string_lossy ( ) . to_string ( ) ;
}
}
let dir = Config ::get_option ( " video-save-directory " ) ;
if ! dir . is_empty ( ) {
return dir ;
}
2022-10-25 10:16:11 +09:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
if let Ok ( home ) = config ::APP_HOME_DIR . read ( ) {
let mut path = home . to_owned ( ) ;
path . push_str ( " /RustDesk/ScreenRecord " ) ;
2023-03-11 00:32:28 +08:00
let dir = try_create ( & std ::path ::Path ::new ( & path ) ) ;
2023-03-10 21:32:43 +08:00
if ! dir . is_empty ( ) {
return dir ;
}
2022-10-25 10:16:11 +09:00
}
2022-10-12 16:06:15 +08:00
if let Some ( user ) = directories_next ::UserDirs ::new ( ) {
if let Some ( video_dir ) = user . video_dir ( ) {
2023-03-10 21:32:43 +08:00
let dir = try_create ( & video_dir . join ( & appname ) ) ;
if ! dir . is_empty ( ) {
return dir ;
}
if video_dir . exists ( ) {
return video_dir . to_string_lossy ( ) . to_string ( ) ;
}
}
if let Some ( desktop_dir ) = user . desktop_dir ( ) {
if desktop_dir . exists ( ) {
return desktop_dir . to_string_lossy ( ) . to_string ( ) ;
}
}
let home = user . home_dir ( ) ;
if home . exists ( ) {
return home . to_string_lossy ( ) . to_string ( ) ;
2022-10-12 16:06:15 +08:00
}
}
2022-10-25 10:16:11 +09:00
2023-03-10 21:32:43 +08:00
// same order as above
2022-10-25 10:16:11 +09:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-11-13 18:11:13 +08:00
if let Some ( home ) = crate ::platform ::get_active_user_home ( ) {
2022-10-12 16:06:15 +08:00
let name = if cfg! ( target_os = " macos " ) {
" Movies "
} else {
" Videos "
} ;
2023-03-10 21:32:43 +08:00
let video_dir = home . join ( name ) ;
let dir = try_create ( & video_dir . join ( & appname ) ) ;
if ! dir . is_empty ( ) {
return dir ;
}
if video_dir . exists ( ) {
return video_dir . to_string_lossy ( ) . to_string ( ) ;
}
let desktop_dir = home . join ( " Desktop " ) ;
if desktop_dir . exists ( ) {
return desktop_dir . to_string_lossy ( ) . to_string ( ) ;
}
if home . exists ( ) {
return home . to_string_lossy ( ) . to_string ( ) ;
}
2022-10-12 16:06:15 +08:00
}
2022-10-25 10:16:11 +09:00
2022-10-12 16:06:15 +08:00
if let Ok ( exe ) = std ::env ::current_exe ( ) {
2023-03-10 21:32:43 +08:00
if let Some ( parent ) = exe . parent ( ) {
let dir = try_create ( & parent . join ( " videos " ) ) ;
if ! dir . is_empty ( ) {
return dir ;
}
// basically exist
return parent . to_string_lossy ( ) . to_string ( ) ;
2022-10-12 16:06:15 +08:00
}
}
2024-05-08 17:04:53 +08:00
Default ::default ( )
2022-09-15 17:31:28 +08:00
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
pub fn get_api_server ( ) -> String {
crate ::get_api_server (
2023-06-24 16:13:20 +08:00
get_option ( " api-server " ) ,
get_option ( " custom-rendezvous-server " ) ,
2022-05-26 18:11:00 +08:00
)
}
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-08-15 11:08:42 +08:00
pub fn has_hwcodec ( ) -> bool {
2024-04-18 13:12:45 +08:00
// Has real hardware codec using gpu
2024-07-12 11:08:51 +08:00
( cfg! ( feature = " hwcodec " ) & & cfg! ( not ( target_os = " ios " ) ) ) | | cfg! ( feature = " mediacodec " )
2022-08-15 11:08:42 +08:00
}
2024-01-02 16:58:10 +08:00
#[ inline ]
2024-04-12 17:26:24 +08:00
pub fn has_vram ( ) -> bool {
cfg! ( feature = " vram " )
2024-01-02 16:58:10 +08:00
}
2023-03-31 16:10:52 +08:00
#[ cfg(feature = " flutter " ) ]
#[ inline ]
pub fn supported_hwdecodings ( ) -> ( bool , bool ) {
2024-05-28 16:42:30 +08:00
let decoding =
scrap ::codec ::Decoder ::supported_decodings ( None , use_texture_render ( ) , None , & vec! [ ] ) ;
2024-01-02 16:58:10 +08:00
#[ allow(unused_mut) ]
let ( mut h264 , mut h265 ) = ( decoding . ability_h264 > 0 , decoding . ability_h265 > 0 ) ;
2024-04-12 17:26:24 +08:00
#[ cfg(feature = " vram " ) ]
2024-01-02 16:58:10 +08:00
{
// supported_decodings check runtime luid
2024-04-12 17:26:24 +08:00
let vram = scrap ::vram ::VRamDecoder ::possible_available_without_check ( ) ;
if vram . 0 {
2024-01-02 16:58:10 +08:00
h264 = true ;
}
2024-04-12 17:26:24 +08:00
if vram . 1 {
2024-01-02 16:58:10 +08:00
h265 = true ;
}
}
( h264 , h265 )
2023-03-31 16:10:52 +08:00
}
2022-11-10 21:25:12 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
#[ inline ]
pub fn is_root ( ) -> bool {
crate ::platform ::is_root ( )
}
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
2022-09-27 13:30:49 +08:00
#[ inline ]
pub fn is_root ( ) -> bool {
2022-09-29 13:07:37 +08:00
false
2022-09-27 13:30:49 +08:00
}
2022-11-10 21:25:12 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " flutter " )) ]
2022-09-13 22:48:14 +08:00
#[ inline ]
2022-08-19 15:44:19 +08:00
pub fn check_super_user_permission ( ) -> bool {
2023-02-25 04:55:37 -08:00
#[ cfg(any(windows, target_os = " linux " , target_os = " macos " )) ]
2022-08-19 15:44:19 +08:00
return crate ::platform ::check_super_user_permission ( ) . unwrap_or ( false ) ;
2023-02-25 04:55:37 -08:00
#[ cfg(not(any(windows, target_os = " linux " , target_os = " macos " ))) ]
return true ;
2022-08-19 15:44:19 +08:00
}
2023-08-01 22:19:38 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " , feature = " flutter " ))) ]
pub fn check_zombie ( ) {
2022-05-26 18:11:00 +08:00
let mut deads = Vec ::new ( ) ;
loop {
2023-08-01 22:19:38 +08:00
let mut lock = CHILDREN . lock ( ) . unwrap ( ) ;
2022-05-26 18:11:00 +08:00
let mut n = 0 ;
for ( id , c ) in lock . 1. iter_mut ( ) {
if let Ok ( Some ( _ ) ) = c . try_wait ( ) {
deads . push ( id . clone ( ) ) ;
n + = 1 ;
}
}
for ref id in deads . drain ( .. ) {
lock . 1. remove ( id ) ;
}
if n > 0 {
lock . 0 = true ;
}
drop ( lock ) ;
std ::thread ::sleep ( std ::time ::Duration ::from_millis ( 100 ) ) ;
}
}
2023-08-01 22:19:38 +08:00
#[ inline ]
#[ cfg(not(any(target_os = " android " , target_os = " ios " , feature = " flutter " ))) ]
pub fn recent_sessions_updated ( ) -> bool {
let mut children = CHILDREN . lock ( ) . unwrap ( ) ;
if children . 0 {
children . 0 = false ;
true
} else {
false
}
}
#[ cfg(not(any(target_os = " android " , target_os = " ios " , feature = " flutter " ))) ]
pub fn new_remote ( id : String , remote_type : String , force_relay : bool ) {
let mut lock = CHILDREN . lock ( ) . unwrap ( ) ;
let mut args = vec! [ format! ( " -- {} " , remote_type ) , id . clone ( ) ] ;
if force_relay {
args . push ( " " . to_string ( ) ) ; // password
args . push ( " --relay " . to_string ( ) ) ;
}
let key = ( id . clone ( ) , remote_type . clone ( ) ) ;
if let Some ( c ) = lock . 1. get_mut ( & key ) {
if let Ok ( Some ( _ ) ) = c . try_wait ( ) {
lock . 1. remove ( & key ) ;
} else {
if remote_type = = " rdp " {
allow_err! ( c . kill ( ) ) ;
std ::thread ::sleep ( std ::time ::Duration ::from_millis ( 30 ) ) ;
c . try_wait ( ) . ok ( ) ;
lock . 1. remove ( & key ) ;
} else {
return ;
}
}
}
match crate ::run_me ( args ) {
Ok ( child ) = > {
lock . 1. insert ( key , child ) ;
}
Err ( err ) = > {
log ::error! ( " Failed to spawn remote: {} " , err ) ;
}
}
}
2023-03-27 19:13:29 +08:00
// Make sure `SENDER` is inited here.
#[ inline ]
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-11-20 15:53:08 +08:00
pub fn start_option_status_sync ( ) {
2023-03-27 19:13:29 +08:00
let _sender = SENDER . lock ( ) . unwrap ( ) ;
2022-11-20 15:53:08 +08:00
}
// not call directly
2023-03-27 19:13:29 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-11-20 15:53:08 +08:00
fn check_connect_status ( reconnect : bool ) -> mpsc ::UnboundedSender < ipc ::Data > {
2022-05-26 18:11:00 +08:00
let ( tx , rx ) = mpsc ::unbounded_channel ::< ipc ::Data > ( ) ;
std ::thread ::spawn ( move | | check_connect_status_ ( reconnect , rx ) ) ;
tx
}
2022-11-09 15:04:24 +08:00
#[ cfg(feature = " flutter " ) ]
2023-05-30 15:32:19 +08:00
pub fn account_auth ( op : String , id : String , uuid : String , remember_me : bool ) {
2023-08-08 21:25:44 +08:00
account ::OidcSession ::account_auth ( get_api_server ( ) , op , id , uuid , remember_me ) ;
2022-10-20 23:03:54 +08:00
}
2022-11-09 15:04:24 +08:00
#[ cfg(feature = " flutter " ) ]
2022-10-22 22:19:14 +08:00
pub fn account_auth_cancel ( ) {
account ::OidcSession ::auth_cancel ( ) ;
}
2022-11-09 15:04:24 +08:00
#[ cfg(feature = " flutter " ) ]
2022-10-22 22:19:14 +08:00
pub fn account_auth_result ( ) -> String {
2023-06-22 12:18:03 +08:00
serde_json ::to_string ( & account ::OidcSession ::get_result ( ) ) . unwrap_or_default ( )
2022-10-20 23:03:54 +08:00
}
2023-02-01 19:56:57 +08:00
#[ cfg(feature = " flutter " ) ]
pub fn set_user_default_option ( key : String , value : String ) {
use hbb_common ::config ::UserDefaultConfig ;
UserDefaultConfig ::load ( ) . set ( key , value ) ;
}
#[ cfg(feature = " flutter " ) ]
pub fn get_user_default_option ( key : String ) -> String {
use hbb_common ::config ::UserDefaultConfig ;
UserDefaultConfig ::load ( ) . get ( & key )
}
2023-04-19 14:39:22 +08:00
pub fn get_fingerprint ( ) -> String {
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
if Config ::get_key_confirmed ( ) {
return crate ::common ::pk_to_fingerprint ( Config ::get_key_pair ( ) . 1 ) ;
} else {
return " " . to_owned ( ) ;
}
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return ipc ::get_fingerprint ( ) ;
}
2023-08-09 20:27:52 +08:00
#[ inline ]
pub fn get_login_device_info ( ) -> LoginDeviceInfo {
2023-08-09 21:25:56 +08:00
LoginDeviceInfo {
// std::env::consts::OS is better than whoami::platform() here.
os : std ::env ::consts ::OS . to_owned ( ) ,
r#type : " client " . to_owned ( ) ,
name : crate ::common ::hostname ( ) ,
}
2023-08-09 20:27:52 +08:00
}
#[ inline ]
pub fn get_login_device_info_json ( ) -> String {
2023-08-11 19:28:25 +08:00
serde_json ::to_string ( & get_login_device_info ( ) ) . unwrap_or ( " {} " . to_string ( ) )
2023-08-09 20:27:52 +08:00
}
2023-01-09 02:30:35 -05:00
// notice: avoiding create ipc connection repeatedly,
2022-05-26 18:11:00 +08:00
// because windows named pipe has serious memory leak issue.
2023-03-27 19:13:29 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-05-26 18:11:00 +08:00
#[ tokio::main(flavor = " current_thread " ) ]
2022-11-20 15:53:08 +08:00
async fn check_connect_status_ ( reconnect : bool , rx : mpsc ::UnboundedReceiver < ipc ::Data > ) {
2023-06-24 21:09:45 +08:00
#[ cfg(not(feature = " flutter " )) ]
2022-05-26 18:11:00 +08:00
let mut key_confirmed = false ;
let mut rx = rx ;
let mut mouse_time = 0 ;
2023-06-24 21:09:45 +08:00
#[ cfg(not(feature = " flutter " )) ]
2022-05-26 18:11:00 +08:00
let mut id = " " . to_owned ( ) ;
2023-11-14 12:11:38 +08:00
#[ cfg(any(
target_os = " windows " ,
all (
any ( target_os = " linux " , target_os = " macos " ) ,
feature = " unix-file-copy-paste "
)
) ) ]
2023-06-18 20:23:54 +08:00
let mut enable_file_transfer = " " . to_owned ( ) ;
2024-09-08 12:37:41 +08:00
let is_cm = crate ::common ::is_cm ( ) ;
2023-06-18 20:23:54 +08:00
2022-05-26 18:11:00 +08:00
loop {
if let Ok ( mut c ) = ipc ::connect ( 1000 , " " ) . await {
2024-02-18 21:18:00 +08:00
let mut timer = crate ::rustdesk_interval ( time ::interval ( time ::Duration ::from_secs ( 1 ) ) ) ;
2022-05-26 18:11:00 +08:00
loop {
tokio ::select! {
res = c . next ( ) = > {
match res {
Err ( err ) = > {
log ::error! ( " ipc connection closed: {} " , err ) ;
2024-09-08 12:37:41 +08:00
if is_cm {
crate ::ui_cm_interface ::quit_cm ( ) ;
}
2022-05-26 18:11:00 +08:00
break ;
}
2023-06-24 21:09:45 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-05-26 18:11:00 +08:00
Ok ( Some ( ipc ::Data ::MouseMoveTime ( v ) ) ) = > {
mouse_time = v ;
2023-06-24 21:09:45 +08:00
UI_STATUS . lock ( ) . unwrap ( ) . mouse_time = v ;
2022-05-26 18:11:00 +08:00
}
Ok ( Some ( ipc ::Data ::Options ( Some ( v ) ) ) ) = > {
2022-11-23 09:41:05 +08:00
* OPTIONS . lock ( ) . unwrap ( ) = v ;
* OPTION_SYNCED . lock ( ) . unwrap ( ) = true ;
2023-06-18 20:23:54 +08:00
2023-10-29 20:49:43 +08:00
#[ cfg(any(
2023-10-29 23:35:55 +08:00
target_os = " windows " ,
2023-10-29 20:49:43 +08:00
all (
any ( target_os = " linux " , target_os = " macos " ) ,
feature = " unix-file-copy-paste "
)
2023-10-29 20:10:39 +08:00
) ) ]
2023-06-18 20:23:54 +08:00
{
2024-07-24 17:20:58 +08:00
let b = OPTIONS . lock ( ) . unwrap ( ) . get ( OPTION_ENABLE_FILE_TRANSFER ) . map ( | x | x . to_string ( ) ) . unwrap_or_default ( ) ;
2023-06-18 20:23:54 +08:00
if b ! = enable_file_transfer {
2024-07-24 17:20:58 +08:00
clipboard ::ContextSend ::enable ( option2bool ( OPTION_ENABLE_FILE_TRANSFER , & b ) ) ;
2023-06-18 20:23:54 +08:00
enable_file_transfer = b ;
}
}
2022-05-26 18:11:00 +08:00
}
Ok ( Some ( ipc ::Data ::Config ( ( name , Some ( value ) ) ) ) ) = > {
if name = = " id " {
2023-06-24 21:09:45 +08:00
#[ cfg(not(feature = " flutter " )) ]
{
id = value ;
}
2022-08-01 20:42:30 +08:00
} else if name = = " temporary-password " {
* TEMPORARY_PASSWD . lock ( ) . unwrap ( ) = value ;
2022-05-26 18:11:00 +08:00
}
}
2024-04-28 21:08:49 +08:00
Ok ( Some ( ipc ::Data ::VideoConnCount ( Some ( n ) ) ) ) = > {
VIDEO_CONN_COUNT . store ( n , Ordering ::Relaxed ) ;
}
2023-06-24 21:09:45 +08:00
Ok ( Some ( ipc ::Data ::OnlineStatus ( Some ( ( mut x , _c ) ) ) ) ) = > {
2022-05-26 18:11:00 +08:00
if x > 0 {
x = 1
}
2023-06-24 21:09:45 +08:00
#[ cfg(not(feature = " flutter " )) ]
{
key_confirmed = _c ;
}
* UI_STATUS . lock ( ) . unwrap ( ) = UiStatus {
status_num : x as _ ,
#[ cfg(not(feature = " flutter " )) ]
key_confirmed : _c ,
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
mouse_time ,
#[ cfg(not(feature = " flutter " )) ]
id : id . clone ( ) ,
} ;
2022-05-26 18:11:00 +08:00
}
_ = > { }
}
}
Some ( data ) = rx . recv ( ) = > {
allow_err! ( c . send ( & data ) . await ) ;
}
_ = timer . tick ( ) = > {
c . send ( & ipc ::Data ::OnlineStatus ( None ) ) . await . ok ( ) ;
c . send ( & ipc ::Data ::Options ( None ) ) . await . ok ( ) ;
c . send ( & ipc ::Data ::Config ( ( " id " . to_owned ( ) , None ) ) ) . await . ok ( ) ;
2022-08-01 20:42:30 +08:00
c . send ( & ipc ::Data ::Config ( ( " temporary-password " . to_owned ( ) , None ) ) ) . await . ok ( ) ;
2024-04-28 21:08:49 +08:00
c . send ( & ipc ::Data ::VideoConnCount ( None ) ) . await . ok ( ) ;
2022-05-26 18:11:00 +08:00
}
}
}
}
if ! reconnect {
OPTIONS
. lock ( )
. unwrap ( )
. insert ( " ipc-closed " . to_owned ( ) , " Y " . to_owned ( ) ) ;
break ;
}
2023-06-24 21:09:45 +08:00
* UI_STATUS . lock ( ) . unwrap ( ) = UiStatus {
status_num : - 1 ,
#[ cfg(not(feature = " flutter " )) ]
key_confirmed ,
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
mouse_time ,
#[ cfg(not(feature = " flutter " )) ]
id : id . clone ( ) ,
} ;
2022-05-26 18:11:00 +08:00
sleep ( 1. ) . await ;
}
}
2022-11-23 09:41:05 +08:00
#[ allow(dead_code) ]
pub fn option_synced ( ) -> bool {
2023-06-24 21:09:45 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2023-06-24 16:13:20 +08:00
{
OPTION_SYNCED . lock ( ) . unwrap ( ) . clone ( )
}
2023-06-24 21:09:45 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
2023-06-24 16:13:20 +08:00
{
true
}
2022-11-23 09:41:05 +08:00
}
2023-04-17 19:26:39 +08:00
#[ cfg(any(target_os = " android " , feature = " flutter " )) ]
#[ cfg(not(any(target_os = " ios " ))) ]
2022-09-07 18:57:49 +08:00
#[ tokio::main(flavor = " current_thread " ) ]
pub ( crate ) async fn send_to_cm ( data : & ipc ::Data ) {
if let Ok ( mut c ) = ipc ::connect ( 1000 , " _cm " ) . await {
c . send ( data ) . await . ok ( ) ;
}
}
2022-05-26 18:11:00 +08:00
const INVALID_FORMAT : & 'static str = " Invalid format " ;
const UNKNOWN_ERROR : & 'static str = " Unknown error " ;
2023-06-25 13:14:21 +08:00
#[ inline ]
2022-05-26 18:11:00 +08:00
#[ tokio::main(flavor = " current_thread " ) ]
2023-07-19 17:11:57 +08:00
pub async fn change_id_shared ( id : String , old_id : String ) -> String {
let res = change_id_shared_ ( id , old_id ) . await . to_owned ( ) ;
* ASYNC_JOB_STATUS . lock ( ) . unwrap ( ) = res . clone ( ) ;
res
2023-06-25 13:14:21 +08:00
}
pub async fn change_id_shared_ ( id : String , old_id : String ) -> & 'static str {
2022-05-26 18:11:00 +08:00
if ! hbb_common ::is_valid_custom_id ( & id ) {
return INVALID_FORMAT ;
}
2022-09-16 21:52:08 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2023-07-02 17:13:23 +08:00
let uuid = Bytes ::from (
hbb_common ::machine_uid ::get ( )
. unwrap_or ( " " . to_owned ( ) )
. as_bytes ( )
. to_vec ( ) ,
) ;
2022-09-16 21:52:08 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
2023-06-25 15:37:39 +08:00
let uuid = Bytes ::from ( hbb_common ::get_uuid ( ) ) ;
2022-09-16 21:52:08 +08:00
2022-05-26 18:11:00 +08:00
if uuid . is_empty ( ) {
2022-09-16 21:52:08 +08:00
log ::error! ( " Failed to change id, uuid is_empty " ) ;
2022-05-26 18:11:00 +08:00
return UNKNOWN_ERROR ;
}
2022-09-16 21:52:08 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-05-26 18:11:00 +08:00
let rendezvous_servers = crate ::ipc ::get_rendezvous_servers ( 1_000 ) . await ;
2022-09-16 21:52:08 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
let rendezvous_servers = Config ::get_rendezvous_servers ( ) ;
2022-05-26 18:11:00 +08:00
let mut futs = Vec ::new ( ) ;
let err : Arc < Mutex < & str > > = Default ::default ( ) ;
for rendezvous_server in rendezvous_servers {
let err = err . clone ( ) ;
let id = id . to_owned ( ) ;
let uuid = uuid . clone ( ) ;
let old_id = old_id . clone ( ) ;
futs . push ( tokio ::spawn ( async move {
let tmp = check_id ( rendezvous_server , old_id , id , uuid ) . await ;
if ! tmp . is_empty ( ) {
* err . lock ( ) . unwrap ( ) = tmp ;
}
} ) ) ;
}
join_all ( futs ) . await ;
let err = * err . lock ( ) . unwrap ( ) ;
if err . is_empty ( ) {
2022-09-16 21:52:08 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-05-26 18:11:00 +08:00
crate ::ipc ::set_config_async ( " id " , id . to_owned ( ) ) . await . ok ( ) ;
2022-09-16 21:52:08 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
{
Config ::set_key_confirmed ( false ) ;
Config ::set_id ( & id ) ;
}
2022-05-26 18:11:00 +08:00
}
err
}
async fn check_id (
rendezvous_server : String ,
old_id : String ,
id : String ,
2023-06-25 15:37:39 +08:00
uuid : Bytes ,
2022-05-26 18:11:00 +08:00
) -> & 'static str {
2022-12-28 13:52:13 +08:00
if let Ok ( mut socket ) = hbb_common ::socket_client ::connect_tcp (
2022-05-26 18:11:00 +08:00
crate ::check_port ( rendezvous_server , RENDEZVOUS_PORT ) ,
2023-05-14 18:17:02 +08:00
CONNECT_TIMEOUT ,
2022-05-26 18:11:00 +08:00
)
. await
{
let mut msg_out = Message ::new ( ) ;
msg_out . set_register_pk ( RegisterPk {
old_id ,
id ,
2023-06-25 15:37:39 +08:00
uuid ,
2022-05-26 18:11:00 +08:00
.. Default ::default ( )
} ) ;
let mut ok = false ;
if socket . send ( & msg_out ) . await . is_ok ( ) {
2023-05-14 18:17:02 +08:00
if let Some ( msg_in ) =
crate ::common ::get_next_nonkeyexchange_msg ( & mut socket , None ) . await
{
match msg_in . union {
Some ( rendezvous_message ::Union ::RegisterPkResponse ( rpr ) ) = > {
2023-07-22 14:16:41 +08:00
match rpr . result . enum_value ( ) {
Ok ( register_pk_response ::Result ::OK ) = > {
2023-05-14 18:17:02 +08:00
ok = true ;
2022-05-26 18:11:00 +08:00
}
2023-07-22 14:16:41 +08:00
Ok ( register_pk_response ::Result ::ID_EXISTS ) = > {
2023-05-14 18:17:02 +08:00
return " Not available " ;
}
2023-07-22 14:16:41 +08:00
Ok ( register_pk_response ::Result ::TOO_FREQUENT ) = > {
2023-05-14 18:17:02 +08:00
return " Too frequent " ;
}
2023-07-22 14:16:41 +08:00
Ok ( register_pk_response ::Result ::NOT_SUPPORT ) = > {
2023-05-14 18:17:02 +08:00
return " server_not_support " ;
}
2023-07-22 14:16:41 +08:00
Ok ( register_pk_response ::Result ::SERVER_ERROR ) = > {
2023-05-14 18:17:02 +08:00
return " Server error " ;
}
2023-07-22 14:16:41 +08:00
Ok ( register_pk_response ::Result ::INVALID_ID_FORMAT ) = > {
2023-05-14 18:17:02 +08:00
return INVALID_FORMAT ;
}
_ = > { }
2022-05-26 18:11:00 +08:00
}
}
2023-05-14 18:17:02 +08:00
_ = > { }
2022-05-26 18:11:00 +08:00
}
}
}
if ! ok {
return UNKNOWN_ERROR ;
}
} else {
return " Failed to connect to rendezvous server " ;
}
" "
}
2023-02-26 11:23:43 +08:00
// if it's relay id, return id processed, otherwise return original id
2023-11-06 20:12:01 +08:00
pub fn handle_relay_id ( id : & str ) -> & str {
2023-02-26 11:23:43 +08:00
if id . ends_with ( r "\r" ) | | id . ends_with ( r "/r" ) {
2023-11-06 20:12:01 +08:00
& id [ 0 .. id . len ( ) - 2 ]
2023-02-26 11:23:43 +08:00
} else {
id
}
}
2023-10-14 18:50:41 +08:00
pub fn support_remove_wallpaper ( ) -> bool {
#[ cfg(any(target_os = " windows " , target_os = " linux " )) ]
return crate ::platform ::WallPaperRemover ::support ( ) ;
#[ cfg(not(any(target_os = " windows " , target_os = " linux " ))) ]
return false ;
}
2024-01-22 16:29:08 +08:00
pub fn has_valid_2fa ( ) -> bool {
let raw = get_option ( " 2fa " ) ;
crate ::auth_2fa ::get_2fa ( Some ( raw ) ) . is_some ( )
}
pub fn generate2fa ( ) -> String {
crate ::auth_2fa ::generate2fa ( )
}
pub fn verify2fa ( code : String ) -> bool {
let res = crate ::auth_2fa ::verify2fa ( code ) ;
if res {
refresh_options ( ) ;
}
res
}
2024-04-18 13:12:45 +08:00
2024-06-27 16:18:41 +08:00
pub fn has_valid_bot ( ) -> bool {
crate ::auth_2fa ::TelegramBot ::get ( ) . map_or ( false , | bot | bot . is_some ( ) )
}
pub fn verify_bot ( token : String ) -> String {
match crate ::auth_2fa ::get_chatid_telegram ( & token ) {
Err ( err ) = > err . to_string ( ) ,
Ok ( None ) = > {
2024-06-27 18:23:51 +08:00
" To activate the bot, simply send a message beginning with a forward slash ( \" / \" ) like \" /hello \" to its chat. " . to_owned ( )
2024-06-27 16:18:41 +08:00
}
_ = > " " . to_owned ( ) ,
}
}
2024-04-18 13:12:45 +08:00
pub fn check_hwcodec ( ) {
#[ cfg(feature = " hwcodec " ) ]
2024-07-12 11:08:51 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2024-04-18 13:12:45 +08:00
{
hwcodec, only process that start ipc server start check process (#8325)
check process send config to ipc server, other process get config from ipc server. Process will save config to toml, and the toml will be used if the config is none.
when start check process: ipc server process start or option changed
from disable to enable
when get config: main window start or option changed from disable to
enable, start_video_audio_threads.
Only windows implements signature, which is used to mark whether the gpu software and hardware information changes. After reboot, the signature doesn't change. https://asawicki.info/news_1773_how_to_programmatically_check_graphics_driver_version, use dxgi way to get software version, it's not consistent with the visible driver version, after updating intel driver with small version change, the signature doesn't change. Linux doesn't use toml file.
Signed-off-by: 21pages <sunboeasy@gmail.com>
2024-06-12 20:40:35 +08:00
use std ::sync ::Once ;
static ONCE : Once = Once ::new ( ) ;
ONCE . call_once ( | | {
if crate ::platform ::is_installed ( ) {
ipc ::notify_server_to_check_hwcodec ( ) . ok ( ) ;
ipc ::client_get_hwcodec_config_thread ( 3 ) ;
} else {
scrap ::hwcodec ::start_check_process ( ) ;
}
} )
2024-04-18 13:12:45 +08:00
}
}
2024-08-07 16:21:38 +08:00
#[ cfg(feature = " flutter " ) ]
pub fn get_unlock_pin ( ) -> String {
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
return String ::default ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return ipc ::get_unlock_pin ( ) ;
}
#[ cfg(feature = " flutter " ) ]
pub fn set_unlock_pin ( pin : String ) -> String {
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
return String ::default ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
match ipc ::set_unlock_pin ( pin , true ) {
Ok ( _ ) = > String ::default ( ) ,
Err ( err ) = > err . to_string ( ) ,
}
}
2024-08-12 18:08:33 +08:00
#[ cfg(feature = " flutter " ) ]
pub fn get_trusted_devices ( ) -> String {
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
return Config ::get_trusted_devices_json ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return ipc ::get_trusted_devices ( ) ;
}
#[ cfg(feature = " flutter " ) ]
pub fn remove_trusted_devices ( json : & str ) {
let hwids = serde_json ::from_str ::< Vec < Bytes > > ( json ) . unwrap_or_default ( ) ;
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
Config ::remove_trusted_devices ( & hwids ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
ipc ::remove_trusted_devices ( hwids ) ;
}
#[ cfg(feature = " flutter " ) ]
pub fn clear_trusted_devices ( ) {
#[ cfg(any(target_os = " android " , target_os = " ios " )) ]
Config ::clear_trusted_devices ( ) ;
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
ipc ::clear_trusted_devices ( ) ;
}
2024-09-04 11:31:13 +08:00
#[ cfg(feature = " flutter " ) ]
pub fn max_encrypt_len ( ) -> usize {
hbb_common ::config ::ENCRYPT_MAX_LEN
}