1use bytes::Buf;
4use bytes::BufMut;
5use bytes::Bytes;
6use bytes::BytesMut;
7use protobuf::error::ProtobufError;
8use protobuf::Message;
9use std::convert::TryFrom;
10use std::convert::TryInto;
11use std::io;
12use std::io::Cursor;
13use std::marker::PhantomData;
14use tokio_util::codec::Decoder;
15use tokio_util::codec::Encoder;
16
17use crate::voice::Clientbound;
18use crate::voice::Serverbound;
19use crate::voice::VoiceCodec;
20use crate::voice::VoicePacket;
21use crate::voice::VoicePacketDst;
22
23#[allow(renamed_and_removed_lints)] #[allow(missing_docs)] pub mod msgs {
27 pub mod id {
29 pub use super::super::generated_id::*;
30 }
31
32 include!(concat!(env!("OUT_DIR"), "/proto/mod.rs"));
33}
34
35#[derive(Clone, Debug, PartialEq)]
37pub struct RawControlPacket {
38 pub id: u16,
42 pub bytes: Bytes,
44}
45
46#[derive(Debug)]
48pub struct RawControlCodec;
49
50impl RawControlCodec {
51 pub fn new() -> Self {
53 Default::default()
54 }
55}
56
57impl Default for RawControlCodec {
58 fn default() -> Self {
59 RawControlCodec
60 }
61}
62
63impl Decoder for RawControlCodec {
64 type Item = RawControlPacket;
65 type Error = io::Error;
66
67 fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<RawControlPacket>, io::Error> {
68 let buf_len = buf.len();
69 if buf_len >= 6 {
70 let mut buf = Cursor::new(buf);
71 let id = buf.get_u16();
72 let len = buf.get_u32() as usize;
73 if len > 0x7f_ffff {
74 Err(io::Error::new(io::ErrorKind::Other, "packet too long"))
75 } else if buf_len >= 6 + len {
76 let mut bytes = buf.into_inner().split_to(6 + len);
77 bytes.advance(6);
78 let bytes = bytes.freeze();
79 Ok(Some(RawControlPacket { id, bytes }))
80 } else {
81 Ok(None)
82 }
83 } else {
84 Ok(None)
85 }
86 }
87}
88
89impl Encoder<RawControlPacket> for RawControlCodec {
90 type Error = io::Error;
91
92 fn encode(&mut self, item: RawControlPacket, dst: &mut BytesMut) -> Result<(), io::Error> {
93 let id = item.id;
94 let bytes = &item.bytes;
95 let len = bytes.len();
96 dst.reserve(6 + len);
97 dst.put_u16(id);
98 dst.put_u32(len as u32);
99 dst.put_slice(bytes);
100 Ok(())
101 }
102}
103
104#[derive(Debug)]
110pub struct ControlCodec<EncodeDst: VoicePacketDst, DecodeDst: VoicePacketDst> {
111 inner: RawControlCodec,
112 _encode_dst: PhantomData<EncodeDst>,
113 _decode_dst: PhantomData<DecodeDst>,
114}
115pub type ServerControlCodec = ControlCodec<Clientbound, Serverbound>;
117pub type ClientControlCodec = ControlCodec<Serverbound, Clientbound>;
119
120impl<EncodeDst: VoicePacketDst, DecodeDst: VoicePacketDst> ControlCodec<EncodeDst, DecodeDst> {
121 pub fn new() -> Self {
123 Default::default()
124 }
125}
126
127impl<EncodeDst: VoicePacketDst, DecodeDst: VoicePacketDst> Default
128 for ControlCodec<EncodeDst, DecodeDst>
129{
130 fn default() -> Self {
131 ControlCodec {
132 inner: RawControlCodec::default(),
133 _encode_dst: PhantomData,
134 _decode_dst: PhantomData,
135 }
136 }
137}
138
139impl<EncodeDst: VoicePacketDst, DecodeDst: VoicePacketDst> Decoder
140 for ControlCodec<EncodeDst, DecodeDst>
141{
142 type Item = ControlPacket<DecodeDst>;
143 type Error = io::Error;
144
145 fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
146 Ok(if let Some(raw_packet) = self.inner.decode(buf)? {
147 Some(raw_packet.try_into()?)
148 } else {
149 None
150 })
151 }
152}
153
154impl<EncodeDst: VoicePacketDst, DecodeDst: VoicePacketDst> Encoder<ControlPacket<EncodeDst>>
155 for ControlCodec<EncodeDst, DecodeDst>
156{
157 type Error = io::Error;
158
159 fn encode(
160 &mut self,
161 item: ControlPacket<EncodeDst>,
162 dst: &mut BytesMut,
163 ) -> Result<(), Self::Error> {
164 self.inner.encode(item.into(), dst)
165 }
166}
167
168macro_rules! define_packet_mappings {
170 ( @def $id:expr, $name:ident) => {
171 #[allow(dead_code)]
172 #[allow(non_upper_case_globals)]
173 pub const $name: u16 = $id;
174 };
175 ( @rec $id:expr, $(#[$attr:meta])* $head:ident ) => {
176 $(#[$attr])*
177 define_packet_mappings!(@def $id, $head);
178 };
179 ( @rec $id:expr, $(#[$attr:meta])* $head:ident, $( $(#[$attr_tail:meta])* $tail:ident ),* ) => {
180 $(#[$attr])*
181 define_packet_mappings!(@def $id, $head);
182 define_packet_mappings!(@rec $id + 1, $($(#[$attr_tail])* $tail),*);
183 };
184 ( $( $(#[$attrs:meta])* $names:ident ),* ) => {
185 define_packet_mappings!(@rec 0, $($(#[$attrs])* $names),*);
186 };
187}
188
189macro_rules! define_packet_from {
191 ( $Dst:ident UDPTunnel($type:ty) ) => {
192 impl<$Dst: VoicePacketDst> From<VoicePacket<Dst>> for RawControlPacket {
193 fn from(msg: VoicePacket<Dst>) -> Self {
194 let mut buf = BytesMut::new();
195 VoiceCodec::<Dst, Dst>::default()
196 .encode(msg, &mut buf)
197 .expect("VoiceEncoder is infallible");
198 Self {
199 id: msgs::id::UDPTunnel,
200 bytes: buf.freeze(),
201 }
202 }
203 }
204 impl<$Dst: VoicePacketDst> TryFrom<RawControlPacket> for VoicePacket<$Dst> {
205 type Error = io::Error;
206
207 fn try_from(packet: RawControlPacket) -> Result<Self, Self::Error> {
208 if packet.id == msgs::id::UDPTunnel {
209 packet.bytes.try_into()
210 } else {
211 Err(io::Error::new(
212 io::ErrorKind::Other,
213 concat!("expected packet of type ", stringify!(UDPTunnel)),
214 ))
215 }
216 }
217 }
218 impl<$Dst: VoicePacketDst> TryFrom<Bytes> for VoicePacket<$Dst> {
219 type Error = io::Error;
220
221 fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
222 VoiceCodec::<$Dst, $Dst>::default()
223 .decode(&mut BytesMut::from(bytes.as_ref()))
224 .map(|it| it.expect("VoiceCodec is stateless"))
225 }
226 }
227 impl<$Dst: VoicePacketDst> From<$type> for ControlPacket<$Dst> {
228 fn from(inner: $type) -> Self {
229 ControlPacket::UDPTunnel(Box::new(inner))
230 }
231 }
232 };
233 ( $Dst:ident $name:ident($type:ty) ) => {
234 impl<$Dst: VoicePacketDst> From<$type> for ControlPacket<$Dst> {
235 fn from(inner: $type) -> Self {
236 ControlPacket::$name(Box::new(inner))
237 }
238 }
239 impl From<$type> for RawControlPacket {
240 fn from(msg: $type) -> Self {
241 Self {
242 id: self::msgs::id::$name,
243 bytes: msg.write_to_bytes().unwrap().into(),
244 }
245 }
246 }
247 impl TryFrom<RawControlPacket> for $type {
248 type Error = ProtobufError;
249
250 fn try_from(packet: RawControlPacket) -> Result<Self, Self::Error> {
251 if packet.id == msgs::id::$name {
252 Self::try_from(packet.bytes)
253 } else {
254 Err(ProtobufError::IoError(io::Error::new(
255 io::ErrorKind::Other,
256 concat!("expected packet of type ", stringify!($name)),
257 )))
258 }
259 }
260 }
261 impl TryFrom<&[u8]> for $type {
262 type Error = ProtobufError;
263
264 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
265 protobuf::parse_from_bytes(bytes)
266 }
267 }
268 impl TryFrom<Bytes> for $type {
269 type Error = ProtobufError;
270
271 fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
272 bytes.as_ref().try_into()
273 }
274 }
275 };
276}
277
278macro_rules! define_packet_enum {
280 ( $Dst:ident $( $(#[$attr:meta])* $name:ident($type:ty) ),* ) => {
281 #[derive(Debug, Clone, PartialEq)]
283 #[allow(clippy::large_enum_variant)]
284 #[non_exhaustive]
285 pub enum ControlPacket<$Dst: VoicePacketDst> {
286 $(
287 #[allow(missing_docs)]
288 $(#[$attr])*
289 $name(Box<$type>),
290 )*
291 Other(RawControlPacket),
293 }
294 impl<Dst: VoicePacketDst> TryFrom<RawControlPacket> for ControlPacket<$Dst> {
295 type Error = ProtobufError;
296
297 fn try_from(packet: RawControlPacket) -> Result<Self, Self::Error> {
298 Ok(match packet.id {
299 $(
300 $(#[$attr])*
301 msgs::id::$name => {
302 ControlPacket::$name(Box::new(packet.bytes.try_into()?))
303 }
304 )*
305 _ => ControlPacket::Other(packet),
306 })
307 }
308 }
309 impl<Dst: VoicePacketDst> From<ControlPacket<$Dst>> for RawControlPacket {
310 fn from(packet: ControlPacket<$Dst>) -> Self {
311 match packet {
312 $(
313 $(#[$attr])*
314 ControlPacket::$name(inner) => (*inner).into(),
315 )*
316 ControlPacket::Other(inner) => inner,
317 }
318 }
319 }
320 impl<Dst: VoicePacketDst> ControlPacket<$Dst> {
321 pub fn name(&self) -> &'static str {
323 match self {
324 $(
325 $(#[$attr])*
326 ControlPacket::$name(_) => stringify!($name),
327 )*
328 ControlPacket::Other(_) => "unknown",
329 }
330 }
331 }
332 };
333}
334
335macro_rules! define_packets {
336 ( < $Dst:ident > $( $(#[$attr:meta])* $name:ident($type:ty), )* ) => {
337 #[allow(missing_docs)]
338 mod generated_id {
339 define_packet_mappings!($($(#[$attr])* $name),*);
340 }
341 define_packet_enum!($Dst $($(#[$attr])* $name($type)),*);
342 $(
343 $(#[$attr])*
344 define_packet_from!($Dst $name($type));
345 )*
346 };
347}
348
349define_packets![
350 <Dst>
351 Version(msgs::Version),
352 UDPTunnel(VoicePacket<Dst>),
353 Authenticate(msgs::Authenticate),
354 Ping(msgs::Ping),
355 Reject(msgs::Reject),
356 ServerSync(msgs::ServerSync),
357 ChannelRemove(msgs::ChannelRemove),
358 ChannelState(msgs::ChannelState),
359 UserRemove(msgs::UserRemove),
360 UserState(msgs::UserState),
361 BanList(msgs::BanList),
362 TextMessage(msgs::TextMessage),
363 PermissionDenied(msgs::PermissionDenied),
364 ACL(msgs::ACL),
365 QueryUsers(msgs::QueryUsers),
366 CryptSetup(msgs::CryptSetup),
367 ContextActionModify(msgs::ContextActionModify),
368 ContextAction(msgs::ContextAction),
369 UserList(msgs::UserList),
370 VoiceTarget(msgs::VoiceTarget),
371 PermissionQuery(msgs::PermissionQuery),
372 CodecVersion(msgs::CodecVersion),
373 UserStats(msgs::UserStats),
374 RequestBlob(msgs::RequestBlob),
375 ServerConfig(msgs::ServerConfig),
376 SuggestConfig(msgs::SuggestConfig),
377 #[cfg(feature = "webrtc-extensions")]
378 WebRTC(msgs::WebRTC),
379 #[cfg(feature = "webrtc-extensions")]
380 IceCandidate(msgs::IceCandidate),
381 #[cfg(feature = "webrtc-extensions")]
382 TalkingState(msgs::TalkingState),
383];