feat(call-to-play)!: coordinate game sessions across peers
Implement the launcher design as a production peer-to-peer feature. Call to Play actions are immutable, validated events broadcast over the existing QUIC control channel, deduplicated in a bounded in-memory history, and exchanged in Hello/HelloAck so late joiners reconstruct current calls. Add the Tauri bridge and modular launcher surfaces for play-now and scheduled calls, check-in, readiness buffers, role-aware controls, chat, tickers, and actual caller launch. A deterministic frontend reducer derives presentation state from replicated history. Extend the JSONL peer harness with publish/list commands and a three-peer live-delivery and late-join scenario. This intentionally raises the only supported wire protocol from version 5 to version 6; older builds are not supported. Document the transport architecture and exclude generated peer-test state from Docker build contexts. Test Plan: - `just fmt` -- passed - `just clippy` -- passed - `just test` -- passed - `just frontend-test` -- passed, 20 tests - `just build` -- passed - `just peer-cli-tests S2 S48` -- passed - `git diff --cached --check` -- passed
This commit is contained in:
31 files changed
+3032
-21
No files matched your search
@@ -12,6 +12,7 @@
|
||||
// Module declarations
|
||||
// =============================================================================
|
||||
|
||||
mod call_to_play;
|
||||
mod config;
|
||||
mod context;
|
||||
mod download;
|
||||
@@ -46,6 +47,7 @@ pub use config::{CHUNK_SIZE, MAX_RETRY_COUNT};
|
||||
pub use error::PeerError;
|
||||
pub use install::{UnpackFuture, Unpacker};
|
||||
use lanspread_db::db::{Game, GameCatalog, GameFileDescription};
|
||||
pub use lanspread_proto::{CallToPlayAction, CallToPlayEvent};
|
||||
pub use migration::{MigrationReport, migrate_legacy_state};
|
||||
pub use peer_db::{
|
||||
MajorityValidationResult,
|
||||
@@ -159,6 +161,8 @@ pub enum PeerEvent {
|
||||
ActiveOperationsChanged {
|
||||
active_operations: Vec<ActiveOperation>,
|
||||
},
|
||||
/// New or requested Call to Play events in replication order.
|
||||
CallToPlayEvents(Vec<CallToPlayEvent>),
|
||||
/// A required peer runtime component failed.
|
||||
RuntimeFailed {
|
||||
component: PeerRuntimeComponent,
|
||||
@@ -259,6 +263,10 @@ pub enum PeerCommand {
|
||||
GetPeerCount,
|
||||
/// Connect directly to a peer address without waiting for mDNS discovery.
|
||||
ConnectPeer(SocketAddr),
|
||||
/// Publish one local Call to Play action to this peer and the LAN.
|
||||
PublishCallToPlay(CallToPlayEvent),
|
||||
/// Request the complete in-memory Call to Play history.
|
||||
GetCallToPlayEvents,
|
||||
}
|
||||
|
||||
/// Optional startup settings for non-GUI callers and tests.
|
||||
@@ -489,6 +497,13 @@ async fn handle_peer_commands(
|
||||
PeerCommand::ConnectPeer(addr) => {
|
||||
handle_connect_peer_command(ctx, tx_notify_ui, addr).await;
|
||||
}
|
||||
PeerCommand::PublishCallToPlay(event) => {
|
||||
call_to_play::publish(ctx, tx_notify_ui, event).await;
|
||||
}
|
||||
PeerCommand::GetCallToPlayEvents => {
|
||||
let events = ctx.call_to_play.read().await.snapshot();
|
||||
events::send(tx_notify_ui, PeerEvent::CallToPlayEvents(events));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user