Cleanup core header and proto code
Some checks failed
Build Linux Binaries / linux/amd64 (push) Has been cancelled
Build Linux Binaries / linux/arm64 (push) Has been cancelled

This commit is contained in:
2026-07-03 12:46:51 +01:00
parent 5c03e5f261
commit bd844e4710
2 changed files with 70 additions and 112 deletions

View File

@@ -1,19 +1,19 @@
// VoiceCat control-plane wire format. SOURCE OF TRUTH for the protocol.
// Spec: docs/protocol.md. Each TCP/TLS frame is [u32 length][encoded Envelope].
// Media frames (voice) are NOT here — they use the fixed binary header in docs/voice.md §2.
// Each TCP/TLS frame is [u32 length][encoded Envelope].
// Media frames (voice) are NOT here — they use a fixed binary header
//
// Extensibility rules (docs/protocol.md §8): never reuse/renumber tags; new oneof arms and
// Extensibility rules: never reuse/renumber tags; new oneof arms and
// fields are additive; gate new features behind capability strings in ClientHello/ServerHello.
syntax = "proto3";
package voicecat.v1;
// ── Envelope ──────────────────────────────────────────────────────────────────
// Envelope
message Envelope {
// Nonzero on a request; echoed in the matching response for correlation. 0 = unsolicited.
uint64 request_id = 1;
oneof body {
// Session / handshake (tags 1019)
// Session / handshake (tags 10-19)
ClientHello client_hello = 10;
ServerHello server_hello = 11;
AuthRequest auth_request = 12;
@@ -22,13 +22,13 @@ message Envelope {
Ping ping = 15;
Pong pong = 16;
// State sync (2029)
// State sync (20-29)
ServerStateSnapshot server_state = 20;
ChannelEvent channel_event = 21;
UserEvent user_event = 22;
SubscribeRequest subscribe = 23;
// Channel operations (3039)
// Channel operations (30-39)
JoinChannelRequest join_channel = 30;
JoinChannelResult join_channel_result = 31;
LeaveChannelRequest leave_channel = 32;
@@ -38,7 +38,7 @@ message Envelope {
MoveUserRequest move_user = 36;
GenericResult generic_result = 37;
// Voice signaling media is on UDP (4049)
// Voice signaling, media is on UDP (40-49)
StreamAnnounce stream_announce = 40;
StreamAnnounceResult stream_announce_result = 41;
StreamStop stream_stop = 42;
@@ -48,18 +48,18 @@ message Envelope {
UnsubscribeVoiceRequest unsubscribe_voice = 46;
VoiceSubscriptionResult voice_subscription_result = 47;
// Text (5059)
// Text (50-59)
TextMessage text_message = 50;
TextMessageAck text_message_ack = 51;
TypingIndicator typing = 52;
// Moderation / permissions (6069)
// Moderation / permissions (60-69)
KickRequest kick = 60;
BanRequest ban = 61;
SetPermissionRequest set_permission = 62;
ServerMuteRequest server_mute = 63;
// Admin account management privileged; accounts are admin-provisioned (7079)
// Admin account management. privileged; accounts are admin-provisioned (70-79)
CreateAccountRequest create_account = 70;
ResetPasswordRequest reset_password = 71;
DeleteAccountRequest delete_account = 72;
@@ -71,18 +71,18 @@ message Envelope {
}
}
// ── Enums ──────────────────────────────────────────────────────────────────────
// Enums
enum ChannelType { CHANNEL_PERMANENT = 0; CHANNEL_TEMPORARY = 1; }
enum ChannelMode { MODE_MONO = 0; MODE_STEREO = 1; }
enum StreamKind { STREAM_MIC = 0; STREAM_SCREEN_AUDIO = 1; STREAM_AUX_DEVICE = 2; }
enum TextScope { TEXT_CHANNEL = 0; TEXT_PRIVATE = 1; TEXT_SERVER = 2; }
enum OpusApplication { OPUS_VOIP = 0; OPUS_AUDIO = 1; OPUS_LOWDELAY = 2; }
// ── Common types ────────────────────────────────────────────────────────────────
// Common types
message AudioConfig {
uint32 codec = 1; // 0 = OPUS
ChannelMode mode = 2;
uint32 sample_rate = 3; // 48000 recommended
uint32 sample_rate = 3;
uint32 bitrate_bps = 4;
uint32 frame_ms = 5; // 2.5/5/10/20/40/60
OpusApplication application = 6;
@@ -90,7 +90,7 @@ message AudioConfig {
uint32 expected_packet_loss = 8; // %
bool dtx = 9;
uint32 complexity = 10; // 0..10
bool dred = 11; // Deep REDundancy (Opus 1.6); off by default
bool dred = 11; // Deep REDundancy (Opus 1.6)
}
message StreamInfo {
@@ -127,7 +127,6 @@ message User {
}
message Permissions {
// Minimal v1 flag set; the moderation milestone expands this. Server-side is authoritative.
bool can_create_temp_channel = 1;
bool can_kick = 2;
bool can_ban = 3;
@@ -136,7 +135,7 @@ message Permissions {
bool is_admin = 6;
}
// ── Session / handshake ─────────────────────────────────────────────────────────
// Session / handshake
message ClientHello {
uint32 proto_version = 1;
repeated string features = 2; // "opus", "fec", "screen-audio", ...
@@ -171,14 +170,14 @@ message AuthResult {
uint64 session_id = 3;
User self = 4;
Permissions permissions = 5;
bytes udp_token = 6; // bind the UDP 5-tuple with this (security.md §3)
bytes udp_token = 6; // bind the UDP 5-tuple with this
}
message Disconnect { uint32 code = 1; string reason = 2; }
message Ping { uint64 nonce = 1; }
message Pong { uint64 nonce = 1; }
// ── State sync ──────────────────────────────────────────────────────────────────
// State sync
message ServerStateSnapshot {
repeated Channel channels = 1;
repeated User users = 2;
@@ -198,7 +197,7 @@ message UserEvent {
}
message SubscribeRequest { repeated uint32 channel_ids = 1; bool presence = 2; }
// ── Channel operations ──────────────────────────────────────────────────────────
// Channel operations
message JoinChannelRequest { uint32 channel_id = 1; string password = 2; }
message JoinChannelResult {
bool ok = 1; string error = 2;
@@ -213,22 +212,19 @@ message DeleteChannelRequest { uint32 channel_id = 1; }
message MoveUserRequest { uint32 user_id = 1; uint32 channel_id = 2; }
message GenericResult { bool ok = 1; uint32 code = 2; string message = 3; }
// ── Voice signaling ─────────────────────────────────────────────────────────────
// Voice signaling
message StreamAnnounce { StreamKind kind = 1; AudioConfig requested_audio = 2; string label = 3; }
message StreamAnnounceResult{ bool ok = 1; string error = 2; uint32 stream_id = 3; uint32 ssrc = 4; AudioConfig effective_audio = 5; }
message StreamStop { uint32 stream_id = 1; }
message StreamStateUpdate { uint32 user_id = 1; uint32 stream_id = 2; bool muted = 3; bool talking = 4; }
message UdpBinding { bytes udp_token = 1; bool ack = 2; }
// Voice-plane subscription. Joining voice = you can hear and send voice in your channel;
// leaving voice = the server stops relaying voice frames to you and you stop receiving.
// Text chat is unaffected. The server toggles a per-session flag checked by the SFU relay's
// recipient filter (docs/protocol.md §5). Result arrives as voice_subscription_result.
message SubscribeVoiceRequest {}
message UnsubscribeVoiceRequest {}
message VoiceSubscriptionResult { bool ok = 1; string error = 2; bool subscribed = 3; }
// ── Text (ephemeral — server does not persist history, docs/protocol.md §5) ──────
// Text
message TextMessage {
TextScope scope = 1;
uint32 target_id = 2; // channel_id or user_id per scope
@@ -240,13 +236,13 @@ message TextMessage {
message TextMessageAck { string client_msg_id = 1; bool ok = 2; }
message TypingIndicator { TextScope scope = 1; uint32 target_id = 2; uint32 user_id = 3; }
// ── Moderation / permissions ─────────────────────────────────────────────────────
// Moderation / permissions
message KickRequest { uint32 user_id = 1; string reason = 2; }
message BanRequest { uint32 user_id = 1; string reason = 2; uint64 expires_unix_ms = 3; }
message SetPermissionRequest { uint32 user_id = 1; Permissions permissions = 2; }
message ServerMuteRequest { uint32 user_id = 1; bool muted = 2; bool deafened = 3; }
// ── Admin account management (privileged) ────────────────────────────────────────
// Admin account management
message CreateAccountRequest { string username = 1; string password = 2; }
message ResetPasswordRequest { string username = 1; string new_password = 2; }
message DeleteAccountRequest { string username = 1; }
@@ -254,5 +250,5 @@ message ListAccountsRequest {}
message AccountEntry { string username = 1; bool is_admin = 2; uint64 created_at_unix_ms = 3; uint64 last_login_unix_ms = 4; }
message ListAccountsResult { repeated AccountEntry accounts = 1; }
// ── Extension escape hatch ───────────────────────────────────────────────────────
// Extension escape hatch
message Extension { string ns = 1; bytes payload = 2; }