feat: add voice packet handling to session

- Add VoiceData event to SessionEvent (codec, packet_id, audio_data, is_whisper)
- Session detects Voice/VoiceWhisper packets and emits VoiceData events
- Add shared_secret() and key_cache_mut() accessors to Client
- Voice packets bypass command processing for lower latency
- 67 tests passing across all crates
This commit is contained in:
ReTeamSpeak
2026-05-12 20:15:56 +09:00
parent 25af2cb295
commit c878d74a6a
2 changed files with 59 additions and 2 deletions
+8
View File
@@ -159,6 +159,14 @@ impl Client {
self.client_id
}
pub fn shared_secret(&self) -> &Option<SharedSecret> {
&self.shared_secret
}
pub fn key_cache_mut(&mut self) -> &mut KeyCache {
&mut self.key_cache
}
/// 开始连接握手
pub fn start_handshake(&mut self) -> Result<Vec<u8>, ProtocolError> {
self.state_machine
+51 -2
View File
@@ -4,7 +4,7 @@ use tokio::sync::mpsc;
use super::client::{ChannelEntry, Client, ClientConfig, ClientEntry, CommandEvent, HandleResult};
use super::state::ConnectionState;
use crate::protocol::Command;
use crate::protocol::{parse_voice_packet, Command, Direction, InPacket, PacketType, VoiceData};
use crate::ProtocolError;
pub enum SessionCommand {
@@ -67,6 +67,12 @@ pub enum SessionEvent {
clients_online: u16,
channels_online: u16,
},
VoiceData {
codec: u8,
packet_id: u16,
audio_data: Vec<u8>,
is_whisper: bool,
},
Error(String),
Disconnected,
}
@@ -256,7 +262,18 @@ impl Session {
tokio::select! {
result = self.socket.recv(&mut buf) => {
let len = result?;
let handle_result = self.client.handle_data(&buf[..len])?;
let data = &buf[..len];
if let Ok(packet) = InPacket::parse(Direction::S2C, data) {
let packet_type = packet.header.flags.packet_type();
if packet_type == PacketType::Voice || packet_type == PacketType::VoiceWhisper {
self.handle_voice_packet(&packet).await;
continue;
}
}
let handle_result = self.client.handle_data(data)?;
for response in &handle_result.responses {
self.socket.send(response).await?;
}
@@ -280,6 +297,38 @@ impl Session {
}
}
async fn handle_voice_packet(&mut self, packet: &InPacket) {
let voice_data = match parse_voice_packet(packet) {
Ok(v) => v,
Err(_) => return,
};
match voice_data {
VoiceData::Normal(voice) => {
let _ = self
.event_tx
.send(SessionEvent::VoiceData {
codec: voice.codec.to_u8(),
packet_id: voice.packet_id,
audio_data: voice.audio_data,
is_whisper: false,
})
.await;
}
VoiceData::Whisper(whisper) => {
let _ = self
.event_tx
.send(SessionEvent::VoiceData {
codec: whisper.codec.to_u8(),
packet_id: whisper.packet_id,
audio_data: whisper.audio_data,
is_whisper: true,
})
.await;
}
}
}
async fn emit_session_event(&self, event: CommandEvent) {
let session_event = match event {
CommandEvent::InitServer {