//! 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, PartialEq, Eq, 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, /// True when the server marks the channel as password-protected. pub has_password: bool, /// Talk power threshold required to speak in this channel. /// `None` means no talk-power restriction. pub needed_talk_power: Option, } /// The target scope of a text message (mirrors TS3 `TextMessageTargetMode`). #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum MessageTarget { /// Broadcast to entire server. Server, /// Broadcast to current channel. Channel, /// Private message to a specific client. Client(u64), /// Poke a specific client. Poke(u64), } /// An in-channel text message from a specific client. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ChatMessage { /// The client id of the sender. pub sender_id: ClientId, /// Nickname of the sender, preserved verbatim. pub sender_name: String, /// Message content, preserved verbatim. pub message: String, /// Target scope of this message. pub target: MessageTarget, } /// A server-activity notification derived from TeamSpeak bookkeeping events. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ServerActivity { /// Human-readable activity line. pub message: String, } /// One connected client on the server. #[derive(Debug, Clone, PartialEq, Eq, 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, /// True when this client has muted microphone/input capture. pub input_muted: bool, /// True when this client has muted speaker/output audio. pub output_muted: bool, /// True when recent inbound voice activity was observed for this client. pub is_speaking: bool, /// True for TeamSpeak ServerQuery clients. pub is_server_query: bool, /// Current talk power value assigned by the server. pub talk_power: i32, /// True when the server has granted talk power regardless of numeric value. pub talk_power_granted: bool, } /// Best-effort profile and live connection details for one online /// client, fetched through the normal TeamSpeak client protocol. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ClientProfile { /// Stable online client id. pub id: ClientId, /// Channel the client is currently in. pub channel: ChannelId, /// Nickname, preserved verbatim per ADR-008. pub name: String, /// TeamSpeak unique id encoded in the canonical base64 form. pub unique_id: String, /// Stable TeamSpeak database id, when visible. pub database_id: Option, /// ISO country code, when the server exposes one. pub country_code: String, /// User description, when visible. pub description: String, /// Client version string, populated by `clientgetvariables`. pub version: String, /// Client platform string, populated by `clientgetvariables`. pub platform: String, /// Account creation time as Unix seconds. pub created_unix_seconds: Option, /// Last connection time as Unix seconds. pub last_connected_unix_seconds: Option, /// Total historical connections, when visible. pub connections_total: Option, /// Current online duration in seconds, when visible. pub online_seconds: Option, /// Current idle time in milliseconds, when visible. pub idle_milliseconds: Option, /// Current ping in milliseconds, when visible. pub ping_milliseconds: Option, /// Current ping deviation in milliseconds, when visible. pub ping_deviation_milliseconds: Option, /// Client address. Empty when permission-gated. pub client_address: String, /// Resolved server group names for the online client. pub server_groups: Vec, /// Resolved channel group name for the online client. pub channel_group: String, /// TeamSpeak avatar file path suffix, when an avatar hash is present. pub avatar_path: String, /// Downloaded bytes this month. pub bytes_downloaded_month: Option, /// Uploaded bytes this month. pub bytes_uploaded_month: Option, /// Downloaded bytes across all time. pub bytes_downloaded_total: Option, /// Uploaded bytes across all time. pub bytes_uploaded_total: Option, /// Client-to-server total packet loss ratio. pub packet_loss_client_to_server_total: Option, /// Server-to-client total packet loss ratio. pub packet_loss_server_to_client_total: Option, } /// Snapshot of the server's published state at a moment in time. #[derive(Debug, Clone, PartialEq, Eq, 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, /// All clients currently known. pub clients: Vec, /// 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 { pub const ROOT: ChannelId = ChannelId(0); } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ProtocolDelta { ClientMoved { client_id: u64, new_channel_id: u64, }, ClientJoined { client_id: u64, channel_id: u64, name: String, input_muted: bool, output_muted: bool, is_server_query: bool, talk_power: i32, talk_power_granted: bool, }, ClientLeft { client_id: u64, name: String, }, ClientUpdated { client_id: u64, input_muted: bool, output_muted: bool, is_server_query: bool, talk_power: i32, talk_power_granted: bool, }, ChannelAdded { id: u64, parent: u64, name: String, order: i64, has_password: bool, needed_talk_power: Option, }, ChannelRemoved { id: u64, }, ChannelUpdated { id: u64, name: String, has_password: bool, needed_talk_power: Option, }, }