Merge pull request #4901 from 21pages/urilink
flutter: file transfer/port forward/rdp command line support
This commit is contained in:
		
						commit
						daa59af5be
					
				| @ -1547,7 +1547,7 @@ Future<bool> initUniLinks() async { | |||||||
|     if (initialLink == null) { |     if (initialLink == null) { | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|     return parseRustdeskUri(initialLink); |     return handleUriLink(uriString: initialLink); | ||||||
|   } catch (err) { |   } catch (err) { | ||||||
|     debugPrintStack(label: "$err"); |     debugPrintStack(label: "$err"); | ||||||
|     return false; |     return false; | ||||||
| @ -1568,7 +1568,7 @@ StreamSubscription? listenUniLinks({handleByFlutter = true}) { | |||||||
|     debugPrint("A uri was received: $uri."); |     debugPrint("A uri was received: $uri."); | ||||||
|     if (uri != null) { |     if (uri != null) { | ||||||
|       if (handleByFlutter) { |       if (handleByFlutter) { | ||||||
|         callUniLinksUriHandler(uri); |         handleUriLink(uri: uri); | ||||||
|       } else { |       } else { | ||||||
|         bind.sendUrlScheme(url: uri.toString()); |         bind.sendUrlScheme(url: uri.toString()); | ||||||
|       } |       } | ||||||
| @ -1581,90 +1581,142 @@ StreamSubscription? listenUniLinks({handleByFlutter = true}) { | |||||||
|   return sub; |   return sub; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Handle command line arguments | enum UriLinkType { | ||||||
| /// |   remoteDesktop, | ||||||
| /// * Returns true if we successfully handle the startup arguments. |   fileTransfer, | ||||||
| bool checkArguments() { |   portForward, | ||||||
|   if (kBootArgs.isNotEmpty) { |   rdp, | ||||||
|     final ret = parseRustdeskUri(kBootArgs.first); | } | ||||||
|     if (ret) { | 
 | ||||||
|       return true; | // uri link handler | ||||||
|  | bool handleUriLink({List<String>? cmdArgs, Uri? uri, String? uriString}) { | ||||||
|  |   List<String>? args; | ||||||
|  |   if (cmdArgs != null) { | ||||||
|  |     args = cmdArgs; | ||||||
|  |     if (args.isNotEmpty && args[0].startsWith(kUniLinksPrefix)) { | ||||||
|  |       final uri = Uri.tryParse(args[0]); | ||||||
|  |       if (uri != null) { | ||||||
|  |         args = urlLinkToCmdArgs(uri); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   // bootArgs:[--connect, 362587269, --switch_uuid, e3d531cc-5dce-41e0-bd06-5d4a2b1eec05] |   } else if (uri != null) { | ||||||
|   // check connect args |     args = urlLinkToCmdArgs(uri); | ||||||
|   var connectIndex = kBootArgs.indexOf("--connect"); |   } else if (uriString != null) { | ||||||
|   if (connectIndex == -1) { |     final uri = Uri.tryParse(uriString); | ||||||
|     return false; |     if (uri != null) { | ||||||
|  |       args = urlLinkToCmdArgs(uri); | ||||||
|     } |     } | ||||||
|   String? id = |  | ||||||
|       kBootArgs.length <= connectIndex + 1 ? null : kBootArgs[connectIndex + 1]; |  | ||||||
|   String? password = |  | ||||||
|       kBootArgs.length <= connectIndex + 2 ? null : kBootArgs[connectIndex + 2]; |  | ||||||
|   if (password != null && password.startsWith("--")) { |  | ||||||
|     password = null; |  | ||||||
|   } |   } | ||||||
|   final switchUuidIndex = kBootArgs.indexOf("--switch_uuid"); |   if (args == null) return false; | ||||||
|   String? switchUuid = kBootArgs.length <= switchUuidIndex + 1 | 
 | ||||||
|       ? null |   UriLinkType? type; | ||||||
|       : kBootArgs[switchUuidIndex + 1]; |   String? id; | ||||||
|   if (id != null) { |   String? password; | ||||||
|     if (id.startsWith(kUniLinksPrefix)) { |   String? switchUuid; | ||||||
|       return parseRustdeskUri(id); |   bool? forceRelay; | ||||||
|     } else { |   for (int i = 0; i < args.length; i++) { | ||||||
|       // remove "--connect xxx" in the `bootArgs` array |     switch (args[i]) { | ||||||
|       kBootArgs.removeAt(connectIndex); |       case '--connect': | ||||||
|       kBootArgs.removeAt(connectIndex); |       case '--play': | ||||||
|       // fallback to peer id |         type = UriLinkType.remoteDesktop; | ||||||
|  |         id = args[i + 1]; | ||||||
|  |         i++; | ||||||
|  |         break; | ||||||
|  |       case '--file-transfer': | ||||||
|  |         type = UriLinkType.fileTransfer; | ||||||
|  |         id = args[i + 1]; | ||||||
|  |         i++; | ||||||
|  |         break; | ||||||
|  |       case '--port-forward': | ||||||
|  |         type = UriLinkType.portForward; | ||||||
|  |         id = args[i + 1]; | ||||||
|  |         i++; | ||||||
|  |         break; | ||||||
|  |       case '--rdp': | ||||||
|  |         type = UriLinkType.rdp; | ||||||
|  |         id = args[i + 1]; | ||||||
|  |         i++; | ||||||
|  |         break; | ||||||
|  |       case '--password': | ||||||
|  |         password = args[i + 1]; | ||||||
|  |         i++; | ||||||
|  |         break; | ||||||
|  |       case '--switch_uuid': | ||||||
|  |         switchUuid = args[i + 1]; | ||||||
|  |         i++; | ||||||
|  |         break; | ||||||
|  |       case '--relay': | ||||||
|  |         forceRelay = true; | ||||||
|  |         break; | ||||||
|  |       default: | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (type != null && id != null) { | ||||||
|  |     switch (type) { | ||||||
|  |       case UriLinkType.remoteDesktop: | ||||||
|         Future.delayed(Duration.zero, () { |         Future.delayed(Duration.zero, () { | ||||||
|         rustDeskWinManager.newRemoteDesktop(id, |           rustDeskWinManager.newRemoteDesktop(id!, | ||||||
|             password: password, switch_uuid: switchUuid); |               password: password, | ||||||
|  |               switch_uuid: switchUuid, | ||||||
|  |               forceRelay: forceRelay); | ||||||
|         }); |         }); | ||||||
|  |         break; | ||||||
|  |       case UriLinkType.fileTransfer: | ||||||
|  |         Future.delayed(Duration.zero, () { | ||||||
|  |           rustDeskWinManager.newFileTransfer(id!, | ||||||
|  |               password: password, forceRelay: forceRelay); | ||||||
|  |         }); | ||||||
|  |         break; | ||||||
|  |       case UriLinkType.portForward: | ||||||
|  |         Future.delayed(Duration.zero, () { | ||||||
|  |           rustDeskWinManager.newPortForward(id!, false, | ||||||
|  |               password: password, forceRelay: forceRelay); | ||||||
|  |         }); | ||||||
|  |         break; | ||||||
|  |       case UriLinkType.rdp: | ||||||
|  |         Future.delayed(Duration.zero, () { | ||||||
|  |           rustDeskWinManager.newPortForward(id!, true, | ||||||
|  |               password: password, forceRelay: forceRelay); | ||||||
|  |         }); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|   } | 
 | ||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Parse `rustdesk://` unilinks | List<String>? urlLinkToCmdArgs(Uri uri) { | ||||||
| /// |   String? command; | ||||||
| /// Returns true if we successfully handle the uri provided. |   String? id; | ||||||
| /// [Functions] |  | ||||||
| /// 1. New Connection: rustdesk://connection/new/your_peer_id |  | ||||||
| bool parseRustdeskUri(String uriPath) { |  | ||||||
|   final uri = Uri.tryParse(uriPath); |  | ||||||
|   if (uri == null) { |  | ||||||
|     debugPrint("uri is not valid: $uriPath"); |  | ||||||
|     return false; |  | ||||||
|   } |  | ||||||
|   return callUniLinksUriHandler(uri); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// uri handler |  | ||||||
| /// |  | ||||||
| /// Returns true if we successfully handle the uri provided. |  | ||||||
| bool callUniLinksUriHandler(Uri uri) { |  | ||||||
|   debugPrint("uni links called: $uri"); |  | ||||||
|   // new connection |  | ||||||
|   String peerId; |  | ||||||
|   if (uri.authority == "connection" && uri.path.startsWith("/new/")) { |   if (uri.authority == "connection" && uri.path.startsWith("/new/")) { | ||||||
|     peerId = uri.path.substring("/new/".length); |     // For compatibility | ||||||
|   } else if (uri.authority == "connect") { |     command = '--connect'; | ||||||
|     peerId = uri.path.substring(1); |     id = uri.path.substring("/new/".length); | ||||||
|   } else if (uri.authority.length > 2 && uri.path.length <= 1) { |   } else if (['connect', "play", 'file-transfer', 'port-forward', 'rdp'] | ||||||
|     // "/" or "" |       .contains(uri.authority)) { | ||||||
|     peerId = uri.authority; |     command = '--${uri.authority}'; | ||||||
|   } else { |     if (uri.path.length > 1) { | ||||||
|     return false; |       id = uri.path.substring(1); | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   List<String> args = List.empty(growable: true); | ||||||
|  |   if (command != null && id != null) { | ||||||
|  |     args.add(command); | ||||||
|  |     args.add(id); | ||||||
|     var param = uri.queryParameters; |     var param = uri.queryParameters; | ||||||
|   String? switch_uuid = param["switch_uuid"]; |  | ||||||
|     String? password = param["password"]; |     String? password = param["password"]; | ||||||
|   Future.delayed(Duration.zero, () { |     if (password != null) args.addAll(['--password', password]); | ||||||
|     rustDeskWinManager.newRemoteDesktop(peerId, |     String? switch_uuid = param["switch_uuid"]; | ||||||
|         password: password, switch_uuid: switch_uuid); |     if (switch_uuid != null) args.addAll(['--switch_uuid', switch_uuid]); | ||||||
|   }); |     if (param["relay"] != null) args.add("--relay"); | ||||||
|   return true; |     return args; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return null; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| connectMainDesktop(String id, | connectMainDesktop(String id, | ||||||
|  | |||||||
| @ -52,10 +52,12 @@ class FileManagerPage extends StatefulWidget { | |||||||
|   const FileManagerPage( |   const FileManagerPage( | ||||||
|       {Key? key, |       {Key? key, | ||||||
|       required this.id, |       required this.id, | ||||||
|  |       required this.password, | ||||||
|       required this.tabController, |       required this.tabController, | ||||||
|       this.forceRelay}) |       this.forceRelay}) | ||||||
|       : super(key: key); |       : super(key: key); | ||||||
|   final String id; |   final String id; | ||||||
|  |   final String? password; | ||||||
|   final bool? forceRelay; |   final bool? forceRelay; | ||||||
|   final DesktopTabController tabController; |   final DesktopTabController tabController; | ||||||
| 
 | 
 | ||||||
| @ -79,7 +81,10 @@ class _FileManagerPageState extends State<FileManagerPage> | |||||||
|   void initState() { |   void initState() { | ||||||
|     super.initState(); |     super.initState(); | ||||||
|     _ffi = FFI(); |     _ffi = FFI(); | ||||||
|     _ffi.start(widget.id, isFileTransfer: true, forceRelay: widget.forceRelay); |     _ffi.start(widget.id, | ||||||
|  |         isFileTransfer: true, | ||||||
|  |         password: widget.password, | ||||||
|  |         forceRelay: widget.forceRelay); | ||||||
|     WidgetsBinding.instance.addPostFrameCallback((_) { |     WidgetsBinding.instance.addPostFrameCallback((_) { | ||||||
|       _ffi.dialogManager |       _ffi.dialogManager | ||||||
|           .showLoading(translate('Connecting...'), onCancel: closeConnection); |           .showLoading(translate('Connecting...'), onCancel: closeConnection); | ||||||
|  | |||||||
| @ -44,6 +44,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> { | |||||||
|         page: FileManagerPage( |         page: FileManagerPage( | ||||||
|           key: ValueKey(params['id']), |           key: ValueKey(params['id']), | ||||||
|           id: params['id'], |           id: params['id'], | ||||||
|  |           password: params['password'], | ||||||
|           tabController: tabController, |           tabController: tabController, | ||||||
|           forceRelay: params['forceRelay'], |           forceRelay: params['forceRelay'], | ||||||
|         ))); |         ))); | ||||||
| @ -72,6 +73,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> { | |||||||
|             page: FileManagerPage( |             page: FileManagerPage( | ||||||
|               key: ValueKey(id), |               key: ValueKey(id), | ||||||
|               id: id, |               id: id, | ||||||
|  |               password: args['password'], | ||||||
|               tabController: tabController, |               tabController: tabController, | ||||||
|               forceRelay: args['forceRelay'], |               forceRelay: args['forceRelay'], | ||||||
|             ))); |             ))); | ||||||
|  | |||||||
| @ -28,11 +28,13 @@ class PortForwardPage extends StatefulWidget { | |||||||
|   const PortForwardPage( |   const PortForwardPage( | ||||||
|       {Key? key, |       {Key? key, | ||||||
|       required this.id, |       required this.id, | ||||||
|  |       required this.password, | ||||||
|       required this.tabController, |       required this.tabController, | ||||||
|       required this.isRDP, |       required this.isRDP, | ||||||
|       this.forceRelay}) |       this.forceRelay}) | ||||||
|       : super(key: key); |       : super(key: key); | ||||||
|   final String id; |   final String id; | ||||||
|  |   final String password; | ||||||
|   final DesktopTabController tabController; |   final DesktopTabController tabController; | ||||||
|   final bool isRDP; |   final bool isRDP; | ||||||
|   final bool? forceRelay; |   final bool? forceRelay; | ||||||
| @ -55,6 +57,7 @@ class _PortForwardPageState extends State<PortForwardPage> | |||||||
|     _ffi = FFI(); |     _ffi = FFI(); | ||||||
|     _ffi.start(widget.id, |     _ffi.start(widget.id, | ||||||
|         isPortForward: true, |         isPortForward: true, | ||||||
|  |         password: widget.password, | ||||||
|         forceRelay: widget.forceRelay, |         forceRelay: widget.forceRelay, | ||||||
|         isRdp: widget.isRDP); |         isRdp: widget.isRDP); | ||||||
|     Get.put(_ffi, tag: 'pf_${widget.id}'); |     Get.put(_ffi, tag: 'pf_${widget.id}'); | ||||||
|  | |||||||
| @ -43,6 +43,7 @@ class _PortForwardTabPageState extends State<PortForwardTabPage> { | |||||||
|         page: PortForwardPage( |         page: PortForwardPage( | ||||||
|           key: ValueKey(params['id']), |           key: ValueKey(params['id']), | ||||||
|           id: params['id'], |           id: params['id'], | ||||||
|  |           password: params['password'], | ||||||
|           tabController: tabController, |           tabController: tabController, | ||||||
|           isRDP: isRDP, |           isRDP: isRDP, | ||||||
|           forceRelay: params['forceRelay'], |           forceRelay: params['forceRelay'], | ||||||
| @ -77,6 +78,7 @@ class _PortForwardTabPageState extends State<PortForwardTabPage> { | |||||||
|             page: PortForwardPage( |             page: PortForwardPage( | ||||||
|               key: ValueKey(args['id']), |               key: ValueKey(args['id']), | ||||||
|               id: id, |               id: id, | ||||||
|  |               password: args['password'], | ||||||
|               isRDP: isRDP, |               isRDP: isRDP, | ||||||
|               tabController: tabController, |               tabController: tabController, | ||||||
|               forceRelay: args['forceRelay'], |               forceRelay: args['forceRelay'], | ||||||
|  | |||||||
| @ -134,7 +134,7 @@ void runMainApp(bool startService) async { | |||||||
|     // Check the startup argument, if we successfully handle the argument, we keep the main window hidden. |     // Check the startup argument, if we successfully handle the argument, we keep the main window hidden. | ||||||
|     final handledByUniLinks = await initUniLinks(); |     final handledByUniLinks = await initUniLinks(); | ||||||
|     debugPrint("handled by uni links: $handledByUniLinks"); |     debugPrint("handled by uni links: $handledByUniLinks"); | ||||||
|     if (handledByUniLinks || checkArguments()) { |     if (handledByUniLinks || handleUriLink(cmdArgs: kBootArgs)) { | ||||||
|       windowManager.hide(); |       windowManager.hide(); | ||||||
|     } else { |     } else { | ||||||
|       windowManager.show(); |       windowManager.show(); | ||||||
|  | |||||||
| @ -248,7 +248,7 @@ class FfiModel with ChangeNotifier { | |||||||
| 
 | 
 | ||||||
|   onUrlSchemeReceived(Map<String, dynamic> evt) { |   onUrlSchemeReceived(Map<String, dynamic> evt) { | ||||||
|     final url = evt['url'].toString().trim(); |     final url = evt['url'].toString().trim(); | ||||||
|     if (url.startsWith(kUniLinksPrefix) && parseRustdeskUri(url)) { |     if (url.startsWith(kUniLinksPrefix) && handleUriLink(uriString: url)) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     switch (url) { |     switch (url) { | ||||||
|  | |||||||
| @ -84,10 +84,12 @@ class RustDeskMultiWindowManager { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<dynamic> newFileTransfer(String remoteId, {bool? forceRelay}) async { |   Future<dynamic> newFileTransfer(String remoteId, | ||||||
|  |       {String? password, bool? forceRelay}) async { | ||||||
|     var msg = jsonEncode({ |     var msg = jsonEncode({ | ||||||
|       "type": WindowType.FileTransfer.index, |       "type": WindowType.FileTransfer.index, | ||||||
|       "id": remoteId, |       "id": remoteId, | ||||||
|  |       "password": password, | ||||||
|       "forceRelay": forceRelay, |       "forceRelay": forceRelay, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| @ -117,11 +119,12 @@ class RustDeskMultiWindowManager { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<dynamic> newPortForward(String remoteId, bool isRDP, |   Future<dynamic> newPortForward(String remoteId, bool isRDP, | ||||||
|       {bool? forceRelay}) async { |       {String? password, bool? forceRelay}) async { | ||||||
|     final msg = jsonEncode({ |     final msg = jsonEncode({ | ||||||
|       "type": WindowType.PortForward.index, |       "type": WindowType.PortForward.index, | ||||||
|       "id": remoteId, |       "id": remoteId, | ||||||
|       "isRDP": isRDP, |       "isRDP": isRDP, | ||||||
|  |       "password": password, | ||||||
|       "forceRelay": forceRelay, |       "forceRelay": forceRelay, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,15 +19,23 @@ pub fn core_main() -> Option<Vec<String>> { | |||||||
|     let mut _is_elevate = false; |     let mut _is_elevate = false; | ||||||
|     let mut _is_run_as_system = false; |     let mut _is_run_as_system = false; | ||||||
|     let mut _is_quick_support = false; |     let mut _is_quick_support = false; | ||||||
|     let mut _is_flutter_connect = false; |     let mut _is_flutter_invoke_new_connection = false; | ||||||
|     let mut arg_exe = Default::default(); |     let mut arg_exe = Default::default(); | ||||||
|     for arg in std::env::args() { |     for arg in std::env::args() { | ||||||
|         if i == 0 { |         if i == 0 { | ||||||
|             arg_exe = arg; |             arg_exe = arg; | ||||||
|         } else if i > 0 { |         } else if i > 0 { | ||||||
|             #[cfg(feature = "flutter")] |             #[cfg(feature = "flutter")] | ||||||
|             if arg == "--connect" || arg == "--play" { |             if [ | ||||||
|                 _is_flutter_connect = true; |                 "--connect", | ||||||
|  |                 "--play", | ||||||
|  |                 "--file-transfer", | ||||||
|  |                 "--port-forward", | ||||||
|  |                 "--rdp", | ||||||
|  |             ] | ||||||
|  |             .contains(&arg.as_str()) | ||||||
|  |             { | ||||||
|  |                 _is_flutter_invoke_new_connection = true; | ||||||
|             } |             } | ||||||
|             if arg == "--elevate" { |             if arg == "--elevate" { | ||||||
|                 _is_elevate = true; |                 _is_elevate = true; | ||||||
| @ -63,7 +71,7 @@ pub fn core_main() -> Option<Vec<String>> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     #[cfg(feature = "flutter")] |     #[cfg(feature = "flutter")] | ||||||
|     if _is_flutter_connect { |     if _is_flutter_invoke_new_connection { | ||||||
|         return core_main_invoke_new_connection(std::env::args()); |         return core_main_invoke_new_connection(std::env::args()); | ||||||
|     } |     } | ||||||
|     let click_setup = cfg!(windows) && args.is_empty() && crate::common::is_setup(&arg_exe); |     let click_setup = cfg!(windows) && args.is_empty() && crate::common::is_setup(&arg_exe); | ||||||
| @ -318,38 +326,48 @@ fn import_config(path: &str) { | |||||||
| /// If it returns [`Some`], then the process will continue, and flutter gui will be started.
 | /// If it returns [`Some`], then the process will continue, and flutter gui will be started.
 | ||||||
| #[cfg(feature = "flutter")] | #[cfg(feature = "flutter")] | ||||||
| fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<String>> { | fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<String>> { | ||||||
|     args.position(|element| { |     let mut authority = None; | ||||||
|         return element == "--connect" || element == "--play"; |     let mut id = None; | ||||||
|     })?; |     let mut param_array = vec![]; | ||||||
|     let mut peer_id = args.next().unwrap_or("".to_string()); |     while let Some(arg) = args.next() { | ||||||
|     if peer_id.is_empty() { |         match arg.as_str() { | ||||||
|         eprintln!("please provide a valid peer id"); |             "--connect" | "--play" | "--file-transfer" | "--port-forward" | "--rdp" => { | ||||||
|         return None; |                 authority = Some((&arg.to_string()[2..]).to_owned()); | ||||||
|  |                 id = args.next(); | ||||||
|             } |             } | ||||||
|  |             "--password" => { | ||||||
|  |                 if let Some(password) = args.next() { | ||||||
|  |                     param_array.push(format!("password={password}")); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             "--relay" => { | ||||||
|  |                 param_array.push(format!("relay=true")); | ||||||
|  |             } | ||||||
|  |             // inner
 | ||||||
|  |             "--switch_uuid" => { | ||||||
|  |                 if let Some(switch_uuid) = args.next() { | ||||||
|  |                     param_array.push(format!("switch_uuid={switch_uuid}")); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             _ => {} | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     let mut uni_links = Default::default(); | ||||||
|  |     if let Some(authority) = authority { | ||||||
|  |         if let Some(mut id) = id { | ||||||
|             let app_name = crate::get_app_name(); |             let app_name = crate::get_app_name(); | ||||||
|             let ext = format!(".{}", app_name.to_lowercase()); |             let ext = format!(".{}", app_name.to_lowercase()); | ||||||
|     if peer_id.ends_with(&ext) { |             if id.ends_with(&ext) { | ||||||
|         peer_id = peer_id.replace(&ext, ""); |                 id = id.replace(&ext, ""); | ||||||
|             } |             } | ||||||
|     let mut switch_uuid = None; |  | ||||||
|     while let Some(item) = args.next() { |  | ||||||
|         if item == "--switch_uuid" { |  | ||||||
|             switch_uuid = args.next(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     let mut param_array = vec![]; |  | ||||||
|     if switch_uuid.is_some() { |  | ||||||
|         let switch_uuid = switch_uuid.map_or("".to_string(), |p| format!("switch_uuid={}", p)); |  | ||||||
|         param_array.push(switch_uuid); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|             let params = param_array.join("&"); |             let params = param_array.join("&"); | ||||||
|             let params_flag = if params.is_empty() { "" } else { "?" }; |             let params_flag = if params.is_empty() { "" } else { "?" }; | ||||||
|     #[allow(unused)] |             uni_links = format!("rustdesk://{}/{}{}{}", authority, id, params_flag, params); | ||||||
|     let uni_links = format!( |         } | ||||||
|         "rustdesk://connection/new/{}{}{}", |     } | ||||||
|         peer_id, params_flag, params |     if uni_links.is_empty() { | ||||||
|     ); |         return None; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     #[cfg(target_os = "linux")] |     #[cfg(target_os = "linux")] | ||||||
|     return try_send_by_dbus(uni_links); |     return try_send_by_dbus(uni_links); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user