1#[derive(Debug, Clone)]
30pub struct PacketEvent {
31 pub channel: String,
33 pub player: String,
36 pub payload: Vec<u8>,
38}
39
40pub trait PacketField: Sized {
47 fn write_to(&self, buf: &mut Vec<u8>);
48 fn read_from(buf: &[u8], pos: &mut usize) -> Option<Self>;
49}
50
51macro_rules! impl_fixed {
52 ($T:ty, $N:literal) => {
53 impl PacketField for $T {
54 fn write_to(&self, buf: &mut Vec<u8>) {
55 buf.extend_from_slice(&self.to_le_bytes());
56 }
57 fn read_from(buf: &[u8], pos: &mut usize) -> Option<Self> {
58 let end = pos.checked_add($N)?;
59 if end > buf.len() { return None; }
60 let v = Self::from_le_bytes(buf[*pos..end].try_into().ok()?);
61 *pos = end;
62 Some(v)
63 }
64 }
65 };
66}
67
68impl_fixed!(i32, 4);
69impl_fixed!(i64, 8);
70impl_fixed!(u32, 4);
71impl_fixed!(u64, 8);
72impl_fixed!(f32, 4);
73impl_fixed!(f64, 8);
74
75impl PacketField for bool {
76 fn write_to(&self, buf: &mut Vec<u8>) { buf.push(*self as u8); }
77 fn read_from(buf: &[u8], pos: &mut usize) -> Option<Self> {
78 let b = *buf.get(*pos)?;
79 *pos += 1;
80 Some(b != 0)
81 }
82}
83
84impl PacketField for String {
85 fn write_to(&self, buf: &mut Vec<u8>) {
86 let bytes = self.as_bytes();
87 (bytes.len() as u32).write_to(buf);
88 buf.extend_from_slice(bytes);
89 }
90 fn read_from(buf: &[u8], pos: &mut usize) -> Option<Self> {
91 let len = u32::read_from(buf, pos)? as usize;
92 let end = pos.checked_add(len)?;
93 if end > buf.len() { return None; }
94 let s = std::str::from_utf8(&buf[*pos..end]).ok()?.to_owned();
95 *pos = end;
96 Some(s)
97 }
98}
99
100impl PacketField for Vec<u8> {
101 fn write_to(&self, buf: &mut Vec<u8>) {
102 (self.len() as u32).write_to(buf);
103 buf.extend_from_slice(self);
104 }
105 fn read_from(buf: &[u8], pos: &mut usize) -> Option<Self> {
106 let len = u32::read_from(buf, pos)? as usize;
107 let end = pos.checked_add(len)?;
108 if end > buf.len() { return None; }
109 let v = buf[*pos..end].to_vec();
110 *pos = end;
111 Some(v)
112 }
113}
114
115pub trait Packet: Sized {
119 fn encode(&self) -> Vec<u8>;
120 fn decode(bytes: &[u8]) -> Option<Self>;
121}
122
123#[macro_export]
143macro_rules! packet {
144 (
145 $(#[$meta:meta])*
146 $vis:vis struct $Name:ident {
147 $( $fvis:vis $field:ident : $ty:ty ),* $(,)?
148 }
149 ) => {
150 $(#[$meta])*
151 $vis struct $Name {
152 $( $fvis $field : $ty, )*
153 }
154
155 impl $crate::Packet for $Name {
156 fn encode(&self) -> ::std::vec::Vec<u8> {
157 let mut buf = ::std::vec::Vec::new();
158 $( $crate::PacketField::write_to(&self.$field, &mut buf); )*
159 buf
160 }
161 fn decode(bytes: &[u8]) -> ::std::option::Option<Self> {
162 let mut pos = 0usize;
163 $(
164 let $field = <$ty as $crate::PacketField>::read_from(bytes, &mut pos)?;
165 )*
166 ::std::option::Option::Some(Self { $( $field, )* })
167 }
168 }
169 };
170}