feat(game): broadcast game presence (GOSSIP_PROTO 3) + per-game background
Steps 5-6 of game detection. BREAKING wire change — bump everyone. Wire (step 5): - PeerState.game: Option<String> (display label only — never appid/source). - SelfPresence.game + to_state carry it (single self-state builder). - GOSSIP_PROTO 2->3, GOSSIP_SIG_DOMAIN v3, version comment bumped together; Cargo MINOR 0.3.0 -> 0.4.0 per VERSIONING.md. v2/v3 isolate into different topics + signature domains, so a coordinated redeploy is required (same as the W4 avatar bump). - Gossip ingest sanitizes incoming game via sanitize_game_label (bidi/ control strip, 64-char/256-byte cap); empty -> None. - Bonus security fix (Codex find): reject inbound gossip frames over a 128KB cap BEFORE serde_json::from_slice — a legit Announce with a full 48KB avatar is ~49KB, so this bounds allocation abuse with headroom. Core wiring: - Spawns the detector at startup; consumes its watch channel in the main select. Detection runs continuously (for the local background); the broadcast is gated by game_presence_enabled (opt-in, default OFF). New commands: SetGamePresenceEnabled (immediate publish/clear, D8), SetGameOverride, SetGameProcessMap. New event: GameChanged. - game_presence_label sanitizes the outgoing label too. Background switch (step 6): - GUI handles GameChanged: stores current_game, swaps background to the per-game override (config.game_backgrounds[id]) or falls back to the W16 default; reuses the existing cached-handle path (no redraw flicker). 397 lib tests (all green), clippy --all-targets clean, full binary builds. Remaining: step 7 UI (opt-in toggle, roster 'Playing' text, manual override control, Settings game-backgrounds + process-map editors). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+8
-2
@@ -26,7 +26,13 @@ pub const FRIENDS_PROTO: u32 = 1;
|
||||
/// v2 (0.3.0): `GossipMessage::Chat` gained an optional file attachment
|
||||
/// (`ChatAttachment`), so a pre-v2 peer can't interpret/serve chat files — bumped
|
||||
/// to fail fast rather than half-work.
|
||||
pub const GOSSIP_PROTO: u32 = 2;
|
||||
///
|
||||
/// v3 (0.4.0): `PeerState` gained an optional `game` presence field (the
|
||||
/// `Playing <name>` status). The field is `#[serde(default)]`, so the bump isn't
|
||||
/// strictly required for decoding — but per the versioning discipline a wire-shape
|
||||
/// change is isolated into its own topic + signature domain so v2 and v3 peers
|
||||
/// never share a swarm. Resync everyone, exactly like the W4 avatar bump.
|
||||
pub const GOSSIP_PROTO: u32 = 3;
|
||||
/// File-transfer plane version (chat attachment request/stream shape). Bump on
|
||||
/// any change. Mirrored in [`FILES_ALPN`].
|
||||
pub const FILES_PROTO: u32 = 1;
|
||||
@@ -41,7 +47,7 @@ pub const FILES_ALPN: &[u8] = b"peerspeak/files/1";
|
||||
/// ed25519 gossip signature domain: `peerspeak-gossip-v<GOSSIP_PROTO>`. Carries
|
||||
/// the gossip protocol version into every signed payload — a version mismatch
|
||||
/// fails verification (cryptographic separation between gossip versions).
|
||||
pub const GOSSIP_SIG_DOMAIN: &str = "peerspeak-gossip-v2";
|
||||
pub const GOSSIP_SIG_DOMAIN: &str = "peerspeak-gossip-v3";
|
||||
|
||||
/// Version-namespace a room topic so peers on different gossip protocol versions
|
||||
/// derive **different subscription topics from the same ticket** and therefore
|
||||
|
||||
Reference in New Issue
Block a user