feat(rustdesk): 完整实现RustDesk协议和P2P连接

重大变更:
- 从prost切换到protobuf 3.4实现完整的RustDesk协议栈
- 新增P2P打洞模块(punch.rs)支持直连和中继回退
- 重构加密系统:临时Curve25519密钥对+Ed25519签名
- 完善HID适配器:支持CapsLock状态同步和修饰键映射
- 添加音频流支持:Opus编码+音频帧适配器
- 优化视频流:改进帧适配器和编码器协商
- 移除pacer.rs简化视频管道

扩展系统:
- 在设置向导中添加扩展步骤(ttyd/rustdesk切换)
- 扩展可用性检测和自动启动
- 新增WebConfig handler用于Web服务器配置

前端改进:
- SetupView增加第4步扩展配置
- 音频设备列表和配置界面
- 新增多语言支持(en-US/zh-CN)
- TypeScript类型生成更新

文档:
- 更新系统架构文档
- 完善config/hid/rustdesk/video/webrtc模块文档
This commit is contained in:
mofeng-git
2026-01-03 19:34:07 +08:00
parent cb7d9882a2
commit 0c82d1a840
49 changed files with 5470 additions and 1983 deletions

View File

@@ -30,23 +30,26 @@ fn main() {
println!("cargo:rerun-if-changed=secrets.toml");
}
/// Compile protobuf files using prost-build
/// Compile protobuf files using protobuf-codegen (same as RustDesk server)
fn compile_protos() {
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
let protos_dir = out_dir.join("protos");
std::fs::create_dir_all(&protos_dir).unwrap();
prost_build::Config::new()
.out_dir(&out_dir)
// Use bytes::Bytes for video/audio frame data to enable zero-copy
.bytes([
"EncodedVideoFrame.data",
"AudioFrame.data",
"CursorData.colors",
])
.compile_protos(
&["protos/rendezvous.proto", "protos/message.proto"],
&["protos/"],
)
protobuf_codegen::Codegen::new()
.pure()
.out_dir(&protos_dir)
.inputs(["protos/rendezvous.proto", "protos/message.proto"])
.include("protos")
.customize(protobuf_codegen::Customize::default().tokio_bytes(true))
.run()
.expect("Failed to compile protobuf files");
// Generate mod.rs for the protos module
let mod_content = r#"pub mod rendezvous;
pub mod message;
"#;
std::fs::write(protos_dir.join("mod.rs"), mod_content).unwrap();
}
/// Generate secrets module from secrets.toml
@@ -60,6 +63,7 @@ fn generate_secrets() {
// Default values if secrets.toml doesn't exist
let mut rustdesk_public_server = String::new();
let mut rustdesk_public_key = String::new();
let mut rustdesk_relay_key = String::new();
let mut turn_server = String::new();
let mut turn_username = String::new();
let mut turn_password = String::new();
@@ -75,6 +79,9 @@ fn generate_secrets() {
if let Some(v) = rustdesk.get("public_key").and_then(|v| v.as_str()) {
rustdesk_public_key = v.to_string();
}
if let Some(v) = rustdesk.get("relay_key").and_then(|v| v.as_str()) {
rustdesk_relay_key = v.to_string();
}
}
// TURN section (for future use)
@@ -109,6 +116,9 @@ pub mod rustdesk {{
/// Public key for the RustDesk server (for client connection)
pub const PUBLIC_KEY: &str = "{}";
/// Relay server authentication key (licence_key for relay server)
pub const RELAY_KEY: &str = "{}";
/// Check if public server is configured
pub const fn has_public_server() -> bool {{
!PUBLIC_SERVER.is_empty()
@@ -134,6 +144,7 @@ pub mod turn {{
"#,
escape_string(&rustdesk_public_server),
escape_string(&rustdesk_public_key),
escape_string(&rustdesk_relay_key),
escape_string(&turn_server),
escape_string(&turn_username),
escape_string(&turn_password),