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:
@@ -159,6 +159,14 @@ impl Client {
|
|||||||
self.client_id
|
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> {
|
pub fn start_handshake(&mut self) -> Result<Vec<u8>, ProtocolError> {
|
||||||
self.state_machine
|
self.state_machine
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use tokio::sync::mpsc;
|
|||||||
|
|
||||||
use super::client::{ChannelEntry, Client, ClientConfig, ClientEntry, CommandEvent, HandleResult};
|
use super::client::{ChannelEntry, Client, ClientConfig, ClientEntry, CommandEvent, HandleResult};
|
||||||
use super::state::ConnectionState;
|
use super::state::ConnectionState;
|
||||||
use crate::protocol::Command;
|
use crate::protocol::{parse_voice_packet, Command, Direction, InPacket, PacketType, VoiceData};
|
||||||
use crate::ProtocolError;
|
use crate::ProtocolError;
|
||||||
|
|
||||||
pub enum SessionCommand {
|
pub enum SessionCommand {
|
||||||
@@ -67,6 +67,12 @@ pub enum SessionEvent {
|
|||||||
clients_online: u16,
|
clients_online: u16,
|
||||||
channels_online: u16,
|
channels_online: u16,
|
||||||
},
|
},
|
||||||
|
VoiceData {
|
||||||
|
codec: u8,
|
||||||
|
packet_id: u16,
|
||||||
|
audio_data: Vec<u8>,
|
||||||
|
is_whisper: bool,
|
||||||
|
},
|
||||||
Error(String),
|
Error(String),
|
||||||
Disconnected,
|
Disconnected,
|
||||||
}
|
}
|
||||||
@@ -256,7 +262,18 @@ impl Session {
|
|||||||
tokio::select! {
|
tokio::select! {
|
||||||
result = self.socket.recv(&mut buf) => {
|
result = self.socket.recv(&mut buf) => {
|
||||||
let len = result?;
|
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 {
|
for response in &handle_result.responses {
|
||||||
self.socket.send(response).await?;
|
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) {
|
async fn emit_session_event(&self, event: CommandEvent) {
|
||||||
let session_event = match event {
|
let session_event = match event {
|
||||||
CommandEvent::InitServer {
|
CommandEvent::InitServer {
|
||||||
|
|||||||
Reference in New Issue
Block a user