Files
netdesk/native/host/src/bin/engine.rs
T

77 lines
3.5 KiB
Rust

//! Standalone NetDesk native host engine. Captures the screen and serves
//! viewers over the NetDesk protocol with the best available H.264 encoder and
//! SendInput injection. Configured via environment:
//! ND_HOST_ID (required) the id viewers connect to
//! ND_PASSWORD (required) session password (never leaves this machine)
//! ND_WS_URL default wss://netdesk.space/ws
//! ND_NAME default "NetDesk (Rust)"
//! ND_MONITOR default 0
//! ND_FPS default 60
//! ND_BITRATE default 8000000
fn main() -> anyhow::Result<()> {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
#[cfg(windows)]
{
let host_id = std::env::var("ND_HOST_ID").map_err(|_| anyhow::anyhow!("set ND_HOST_ID"))?;
let password =
std::env::var("ND_PASSWORD").map_err(|_| anyhow::anyhow!("set ND_PASSWORD"))?;
let cfg = netdesk_host::run::EngineConfig {
ws_url: std::env::var("ND_WS_URL").unwrap_or_else(|_| "wss://netdesk.space/ws".into()),
host_id,
name: std::env::var("ND_NAME").unwrap_or_else(|_| "NetDesk (Rust)".into()),
password,
monitor: envnum("ND_MONITOR", 0),
fps: envnum("ND_FPS", 60),
bitrate: envnum("ND_BITRATE", 8_000_000),
// Host-enforced permissions + approve-before-connect (see run.rs):
// ND_PERM_INPUT / ND_PERM_CLIPBOARD / ND_PERM_FILES / ND_PERM_AUDIO
// (default 1) and ND_APPROVE (default 0).
perms: netdesk_core::host::HostPerms {
input: envflag("ND_PERM_INPUT", true),
clipboard: envflag("ND_PERM_CLIPBOARD", true),
files: envflag("ND_PERM_FILES", true),
audio: envflag("ND_PERM_AUDIO", true),
},
approve: envflag("ND_APPROVE", false),
totp_secret: std::env::var("ND_TOTP").unwrap_or_default(),
// Encrypted direct-IP: ND_DIRECT_PORT makes the host listen on that
// TCP port for a viewer that dials it directly (no relay);
// ND_ALLOW_IPS is an optional CIDR allow-list.
direct_port: std::env::var("ND_DIRECT_PORT").ok().and_then(|s| s.parse().ok()),
allow_ips: std::env::var("ND_ALLOW_IPS").unwrap_or_default(),
// ND_MAX_VIEWERS>1 allows multiple simultaneous direct-IP viewers
// (1 controller + N observers of the one capture).
max_viewers: std::env::var("ND_MAX_VIEWERS")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(1)
.max(1),
};
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?;
let handle = netdesk_host::run::EngineHandle::new();
rt.block_on(netdesk_host::run::run_engine(cfg, handle))?;
}
#[cfg(not(windows))]
println!("engine is Windows-only");
Ok(())
}
#[cfg(windows)]
fn envnum<T: std::str::FromStr>(key: &str, default: T) -> T {
std::env::var(key).ok().and_then(|s| s.parse().ok()).unwrap_or(default)
}
/// "1"/"true"/"yes" = true, "0"/"false"/"no" = false, unset = `default`.
#[cfg(windows)]
fn envflag(key: &str, default: bool) -> bool {
match std::env::var(key).as_deref().map(str::trim) {
Ok("1") | Ok("true") | Ok("yes") => true,
Ok("0") | Ok("false") | Ok("no") => false,
_ => default,
}
}