mumble-rs/src/codec.rs
2024-09-17 00:24:35 +02:00

109 lines
No EOL
3.8 KiB
Rust

use anyhow::bail;
use bytes::{Buf, BufMut, BytesMut};
use prost::Message;
use tokio_util::codec::{Decoder, Encoder};
use crate::MumbleMessage;
use crate::proto::{Authenticate, Version, Ping, CryptSetup, CodecVersion, ChannelState, PermissionQuery, UserState, ServerSync, ServerConfig, UdpTunnel, UserRemove};
pub struct MumbleTcpCodec {}
impl MumbleTcpCodec {
pub fn new() -> Self {
Self {}
}
}
impl Decoder for MumbleTcpCodec {
type Item = MumbleMessage;
type Error = anyhow::Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
if src.len() < 6 {
return Ok(None);
}
let (message_type, rest) = src.split_at(2);
let (message_length, rest) = rest.split_at(4);
let message_type = u16::from_be_bytes(message_type.try_into()?) as usize;
let message_length = u32::from_be_bytes(message_length.try_into()?) as usize;
if message_length+6 > src.len() {
src.reserve(message_length+6-src.len());
return Ok(None);
}
let (message_data, _) = rest.split_at(message_length);
let mut mumble_message: Option<MumbleMessage> = None;
match message_type {
0 => {
mumble_message = Some(MumbleMessage::Version { data: Version::decode(message_data)? });
}
1 => {
mumble_message = Some(MumbleMessage::UDPTunnel { data: UdpTunnel::decode(message_data)? });
}
3 => {
mumble_message = Some(MumbleMessage::Ping { data: Ping::decode(message_data)? });
},
5 => {
mumble_message = Some(MumbleMessage::ServerSync { data: ServerSync::decode(message_data)? });
}
7 => {
mumble_message = Some(MumbleMessage::ChannelState { data: ChannelState::decode(message_data)? });
}
8 => {
mumble_message = Some(MumbleMessage::UserRemove { data: UserRemove::decode(message_data)? });
}
9 => {
mumble_message = Some(MumbleMessage::UserState { data: UserState::decode(message_data)? });
},
15 => {
mumble_message = Some(MumbleMessage::CryptSetup { data: CryptSetup::decode(message_data)? });
}
20 => {
mumble_message = Some(MumbleMessage::PermissionQuery {data: PermissionQuery::decode(message_data)?});
}
21 => {
mumble_message = Some(MumbleMessage::CodecVersion {data: CodecVersion::decode(message_data)?});
},
24 => {
mumble_message = Some(MumbleMessage::ServerConfig {data: ServerConfig::decode(message_data)?});
}
_ => {
eprintln!("Unknown message type {:?}", message_type);
}
}
src.advance(message_length+6);
Ok(mumble_message)
}
}
impl Encoder<MumbleMessage> for MumbleTcpCodec {
type Error = anyhow::Error;
fn encode(&mut self, item: MumbleMessage, dst: &mut BytesMut) -> Result<(), Self::Error> {
let mut message = BytesMut::new();
match item {
MumbleMessage::Version { data } => {
Version::encode(&data, &mut message)?;
dst.put_u16(0);
}
MumbleMessage::Authenticate { data } => {
Authenticate::encode(&data, &mut message)?;
dst.put_u16(2);
},
MumbleMessage::Ping { data } => {
Ping::encode(&data, &mut message)?;
dst.put_u16(3);
}
_ => {
bail!("Could not encode unknown message")
}
}
dst.put_u32(message.len() as u32);
dst.extend_from_slice(&message);
Ok(())
}
}