ab6dda2e5f
M0 (lumen-host) — verified on NVIDIA RTX 5070 Ti / Ubuntu 25.10: headless wlroots → xdg ScreenCast portal → PipeWire → NVENC HEVC → playable file, with each access unit round-tripped through a lumen_core host↔client Session (FEC + packetize + reassemble), 0 mismatches. - capture.rs: SyntheticCapturer + portal capture (ashpd 0.13 + pipewire 0.9), format-aware - encode/linux.rs: NVENC via ffmpeg-next 7 (BGRx/RGB → rgb0, no host-side swscale) - m0.rs: capture→encode→file + lumen-core loopback verification M2 P1 (lumen-host gamestream/) — a stock Moonlight client pairs + launches, verified live: - mDNS _nvstream._tcp + nvhttp /serverinfo (HTTP 47989, mutual-TLS HTTPS 47984) - 4-phase pairing: PIN→AES-128-ECB / SHA-256 / RSA-PKCS1v15 / X.509, custom rustls ClientCertVerifier for the mutual-TLS pairchallenge - /applist, /launch (rikey/rikeyid/mode), hand-rolled RTSP (OPTIONS/DESCRIBE/SETUP×3/ ANNOUNCE/PLAY, one-request-per-TCP-connection per moonlight-common-c's read-to-EOF) - video.rs: GameStream RTP + NV_VIDEO_PACKET wire packetizer, data-shards-only (0% FEC, clean-LAN), unit-tested (single/multi-block) Docs: docs/m2-plan.md (phased plan) + docs/research/ (ground-truth protocol spec). Bootstrap/setup updated for the verified path (libnvidia-gl, render/video groups, GPU EGL, pipewire 0.9). Workspace clippy-clean, tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
43 lines
1.6 KiB
Rust
43 lines
1.6 KiB
Rust
//! The `/serverinfo` capability/status XML Moonlight GETs before pairing and each launch.
|
|
|
|
use super::{Host, APP_VERSION, GFE_VERSION, SERVER_CODEC_MODE_SUPPORT};
|
|
|
|
/// Build the `<root status_code="200">…</root>` serverinfo document. `https` selects the
|
|
/// paired-HTTPS variant (real MAC). Element names are case-sensitive and match what
|
|
/// moonlight-common-c parses.
|
|
pub fn serverinfo_xml(host: &Host, https: bool) -> String {
|
|
// MAC is hidden over plain HTTP; PairStatus reflects the pairing store once the HTTPS
|
|
// path carries per-client identity (a hardening follow-up — 0 for now).
|
|
let mac = if https {
|
|
"01:02:03:04:05:06"
|
|
} else {
|
|
"00:00:00:00:00:00"
|
|
};
|
|
// Over the mutual-TLS HTTPS port the peer is an authenticated (paired) client.
|
|
let pair_status = u8::from(https);
|
|
format!(
|
|
r#"<?xml version="1.0" encoding="utf-8"?>
|
|
<root status_code="200">
|
|
<hostname>{hostname}</hostname>
|
|
<appversion>{APP_VERSION}</appversion>
|
|
<GfeVersion>{GFE_VERSION}</GfeVersion>
|
|
<uniqueid>{uniqueid}</uniqueid>
|
|
<HttpsPort>{https_port}</HttpsPort>
|
|
<ExternalPort>{http_port}</ExternalPort>
|
|
<MaxLumaPixelsHEVC>1869449984</MaxLumaPixelsHEVC>
|
|
<mac>{mac}</mac>
|
|
<LocalIP>{local_ip}</LocalIP>
|
|
<ServerCodecModeSupport>{SERVER_CODEC_MODE_SUPPORT}</ServerCodecModeSupport>
|
|
<PairStatus>{pair_status}</PairStatus>
|
|
<currentgame>0</currentgame>
|
|
<state>SUNSHINE_SERVER_FREE</state>
|
|
</root>
|
|
"#,
|
|
hostname = host.hostname,
|
|
uniqueid = host.uniqueid,
|
|
https_port = host.https_port,
|
|
http_port = host.http_port,
|
|
local_ip = host.local_ip,
|
|
)
|
|
}
|