flutter: file-transfer/port forward/rdp support

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages
2023-07-07 12:22:39 +08:00
parent 6c8c3b4a7a
commit 1f137b3542
9 changed files with 200 additions and 115 deletions

View File

@@ -1547,7 +1547,7 @@ Future<bool> initUniLinks() async {
if (initialLink == null) {
return false;
}
return parseRustdeskUri(initialLink);
return handleUriLink(uriString: initialLink);
} catch (err) {
debugPrintStack(label: "$err");
return false;
@@ -1568,7 +1568,7 @@ StreamSubscription? listenUniLinks({handleByFlutter = true}) {
debugPrint("A uri was received: $uri.");
if (uri != null) {
if (handleByFlutter) {
callUniLinksUriHandler(uri);
handleUriLink(uri: uri);
} else {
bind.sendUrlScheme(url: uri.toString());
}
@@ -1581,90 +1581,142 @@ StreamSubscription? listenUniLinks({handleByFlutter = true}) {
return sub;
}
/// Handle command line arguments
///
/// * Returns true if we successfully handle the startup arguments.
bool checkArguments() {
if (kBootArgs.isNotEmpty) {
final ret = parseRustdeskUri(kBootArgs.first);
if (ret) {
return true;
enum UriLinkType {
remoteDesktop,
fileTransfer,
portForward,
rdp,
}
// 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);
}
}
} else if (uri != null) {
args = urlLinkToCmdArgs(uri);
} else if (uriString != null) {
final uri = Uri.tryParse(uriString);
if (uri != null) {
args = urlLinkToCmdArgs(uri);
}
}
// bootArgs:[--connect, 362587269, --switch_uuid, e3d531cc-5dce-41e0-bd06-5d4a2b1eec05]
// check connect args
var connectIndex = kBootArgs.indexOf("--connect");
if (connectIndex == -1) {
return false;
}
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");
String? switchUuid = kBootArgs.length <= switchUuidIndex + 1
? null
: kBootArgs[switchUuidIndex + 1];
if (id != null) {
if (id.startsWith(kUniLinksPrefix)) {
return parseRustdeskUri(id);
} else {
// remove "--connect xxx" in the `bootArgs` array
kBootArgs.removeAt(connectIndex);
kBootArgs.removeAt(connectIndex);
// fallback to peer id
Future.delayed(Duration.zero, () {
rustDeskWinManager.newRemoteDesktop(id,
password: password, switch_uuid: switchUuid);
});
return true;
if (args == null) return false;
UriLinkType? type;
String? id;
String? password;
String? switchUuid;
bool? forceRelay;
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case '--connect':
case '--play':
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, () {
rustDeskWinManager.newRemoteDesktop(id!,
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 false;
}
/// Parse `rustdesk://` unilinks
///
/// Returns true if we successfully handle the uri provided.
/// [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;
List<String>? urlLinkToCmdArgs(Uri uri) {
String? command;
String? id;
if (uri.authority == "connection" && uri.path.startsWith("/new/")) {
peerId = uri.path.substring("/new/".length);
} else if (uri.authority == "connect") {
peerId = uri.path.substring(1);
} else if (uri.authority.length > 2 && uri.path.length <= 1) {
// "/" or ""
peerId = uri.authority;
} else {
return false;
// For compatibility
command = '--connect';
id = uri.path.substring("/new/".length);
} else if (['connect', "play", 'file-transfer', 'port-forward', 'rdp']
.contains(uri.authority)) {
command = '--${uri.authority}';
if (uri.path.length > 1) {
id = uri.path.substring(1);
}
}
var param = uri.queryParameters;
String? switch_uuid = param["switch_uuid"];
String? password = param["password"];
Future.delayed(Duration.zero, () {
rustDeskWinManager.newRemoteDesktop(peerId,
password: password, switch_uuid: switch_uuid);
});
return true;
List<String> args = List.empty(growable: true);
if (command != null && id != null) {
args.add(command);
args.add(id);
var param = uri.queryParameters;
String? password = param["password"];
if (password != null) args.addAll(['--password', password]);
String? switch_uuid = param["switch_uuid"];
if (switch_uuid != null) args.addAll(['--switch_uuid', switch_uuid]);
if (param["relay"] != null) args.add("--relay");
return args;
}
return null;
}
connectMainDesktop(String id,