Files
chanora/crates/chanora_protocol/src/dto.rs
T
EdisonJwa 181b3368d4 fix(audio,voice,log): six P0 issues from Korean Windows test
1. Voice Bar 'Leave voice' button removed entirely. TeamSpeak users
   are always in some channel; Discord/Mumble-style leave is the
   wrong model. To stop being heard / hearing, mute mic / speaker.
   To physically move, tap a different channel. The voiceLeave
   bridge call + _onLeaveVoice stay as dead code for now (marked
   unused) so existing tests/integrations don't break.

2. voice_join now confirms the move actually applied server-side
   by polling the snapshot for up to 1.5 s and matching our own
   client's channel against the requested one. If the server
   rejected the move (no permission, wrong password, channel
   full), voice_join rolls the selector back to in_channel=false
   and returns Err so the UI surfaces the failure instead of
   showing a fake 'joined' state.

3. ServerSnapshot + BridgeSnapshot gain own_client_id so the UI
   can identify our row without name-matching. find_own_in reads
   it directly.

4. set_self_muted now also clamps the TransmitModeSelector's
   hard_mute when input is muted server-side. Without this, the
   Opus encoder kept producing frames after setInputMuted(true),
   tsclientlib refused each one with 'Sending audio while muted',
   and the log grew to 200 MB on the Korean host.

5. tsclientlib WARN spam suppressed via tracing filter
   (tsclientlib=error). Belt-and-braces on top of fix 4.

6. Log file is now rotated at every launch (not just when >4 MiB).
   Two generations kept: chanora.log.1 (previous) and
   chanora.log.2 (the one before). The bug that produced 200 MB
   files was a chatty subsystem flooding a single session; the
   per-launch rotate keeps disk use bounded by what one session
   can produce in its lifetime.

Bonus Windows fix (separate from the six but found in the same
log): the Raw Input + Hook backends now signal readiness BEFORE
blocking on GetMessageW. Previously init_tx.send was called after
the loop returned (i.e. on WM_QUIT, which never happens during
arming), so the main thread's 2 s readiness probe always timed
out and the backend reported L0Focused even when registration
succeeded. Both run_raw_input_loop and run_hook_loop now take an
init_tx parameter and call report!(true) right after a successful
registration, and report!(false) on every early-fail return.

cargo check --workspace: clean.
cargo test --workspace --lib: 80 passed / 0 failed / 1 ignored.
flutter analyze: clean (6 pre-existing Radio.groupValue infos).
2026-05-16 01:52:47 +08:00

67 lines
2.2 KiB
Rust

//! Public DTOs returned across the protocol boundary. All fields are
//! owned primitives or `String`s; no `tsclientlib` types leak.
use serde::{Deserialize, Serialize};
/// Opaque server-side channel identifier. Internal representation is
/// the upstream u64 but callers must treat it as opaque.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ChannelId(pub u64);
/// Opaque server-side client identifier.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ClientId(pub u64);
/// One channel in the server's tree.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChannelInfo {
/// Stable channel id.
pub id: ChannelId,
/// Parent channel id; `ChannelId(0)` indicates a top-level channel.
pub parent: ChannelId,
/// Display name, preserved verbatim per ADR-008.
pub name: String,
/// Server-side ordering hint.
pub order: i64,
}
/// One connected client on the server.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClientInfo {
/// Stable client id.
pub id: ClientId,
/// Channel the client is currently in.
pub channel: ChannelId,
/// Nickname, preserved verbatim per ADR-008.
pub name: String,
}
/// Snapshot of the server's published state at a moment in time.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerSnapshot {
/// Server name.
pub server_name: String,
/// Server welcome banner. Contains markup from the upstream
/// server (BBCode-like); not parsed here.
pub welcome_message: String,
/// Server platform string.
pub platform: String,
/// Server version string.
pub version: String,
/// All channels currently known.
pub channels: Vec<ChannelInfo>,
/// All clients currently known.
pub clients: Vec<ClientInfo>,
/// Our own client id as the server published it. Used by the
/// core session to confirm that a `move_to_channel` request
/// actually applied (vs being silently rejected by the
/// server's permission check).
pub own_client_id: u64,
}
impl ChannelId {
/// The conventional root sentinel used by TeamSpeak-compatible
/// servers for the top of the channel tree.
pub const ROOT: ChannelId = ChannelId(0);
}