1use bytes::{Bytes, BytesMut};
4
5use crate::codec::{Decode, DecodeResult, Encode, EncodeResult, McWrite, decode_exact};
6use crate::error::DecodeError;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum State {
11 Handshaking,
13 Status,
15 Login,
17 Play,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub enum Direction {
24 Clientbound,
26 Serverbound,
28}
29
30pub trait Packet: Encode + Decode {
32 const ID: i32;
34 const NAME: &'static str;
36 const STATE: State;
38 const DIRECTION: Direction;
40}
41
42pub trait PacketSet: Sized {
44 const STATE: State;
46 const DIRECTION: Direction;
48
49 fn decode_raw(raw: &RawPacket) -> DecodeResult<Self>;
51 fn id(&self) -> i32;
53 fn name(&self) -> &'static str;
55 fn encode_body(&self, w: &mut BytesMut) -> EncodeResult;
57 fn name_of(id: i32) -> Option<&'static str>;
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct RawPacket {
66 pub id: i32,
68 pub body: Bytes,
70}
71
72impl RawPacket {
73 #[inline]
75 pub fn new(id: i32, body: Bytes) -> Self {
76 RawPacket { id, body }
77 }
78
79 #[inline]
81 pub fn decode_as<P: Packet>(&self) -> DecodeResult<P> {
82 if self.id != P::ID {
83 return Err(DecodeError::IdMismatch {
84 expected: P::ID,
85 actual: self.id,
86 });
87 }
88 decode_exact(&self.body)
89 }
90
91 pub fn from_packet<P: Packet>(p: &P) -> Result<Self, crate::error::EncodeError> {
93 let mut w = BytesMut::new();
94 p.encode(&mut w)?;
95 Ok(RawPacket::new(P::ID, w.freeze()))
96 }
97}
98
99#[inline]
101pub fn write_packet<P: Packet>(p: &P, w: &mut BytesMut) -> EncodeResult {
102 w.put_varint(P::ID);
103 p.encode(w)
104}
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
112pub struct PacketFilter {
113 bits: [u64; 4],
114}
115
116impl Default for PacketFilter {
117 fn default() -> Self {
118 Self::all()
119 }
120}
121
122impl PacketFilter {
123 pub const fn all() -> Self {
125 PacketFilter {
126 bits: [u64::MAX; 4],
127 }
128 }
129
130 pub const fn none() -> Self {
132 PacketFilter { bits: [0; 4] }
133 }
134
135 #[must_use]
137 pub const fn with(mut self, id: i32) -> Self {
138 if id >= 0 && id < 256 {
139 self.bits[(id as usize) >> 6] |= 1 << (id & 63);
140 }
141 self
142 }
143
144 #[must_use]
146 pub const fn without(mut self, id: i32) -> Self {
147 if id >= 0 && id < 256 {
148 self.bits[(id as usize) >> 6] &= !(1 << (id & 63));
149 }
150 self
151 }
152
153 pub fn insert(&mut self, id: i32) {
155 *self = self.with(id);
156 }
157
158 pub fn remove(&mut self, id: i32) {
160 *self = self.without(id);
161 }
162
163 #[inline]
165 pub const fn contains(&self, id: i32) -> bool {
166 if id < 0 || id >= 256 {
167 return true;
168 }
169 self.bits[(id as usize) >> 6] & (1 << (id & 63)) != 0
170 }
171
172 #[inline]
174 pub const fn is_all(&self) -> bool {
175 self.bits[0] == u64::MAX
176 && self.bits[1] == u64::MAX
177 && self.bits[2] == u64::MAX
178 && self.bits[3] == u64::MAX
179 }
180}
181
182pub trait Version: Copy + Send + Sync + 'static {
188 const PROTOCOL: i32;
190 const NAME: &'static str;
192 const POSITION_LAYOUT: crate::types::PositionLayout;
194
195 type HandshakingServerbound: PacketSet;
197 type StatusClientbound: PacketSet;
199 type StatusServerbound: PacketSet;
201 type LoginClientbound: PacketSet;
203 type LoginServerbound: PacketSet;
205 type PlayClientbound: PacketSet;
207 type PlayServerbound: PacketSet;
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 #[test]
216 fn filter() {
217 let f = PacketFilter::none().with(0x21).with(200);
218 assert!(f.contains(0x21) && f.contains(200) && !f.contains(0x22));
219 assert!(f.contains(300) && f.contains(-1));
220 assert!(PacketFilter::all().is_all() && !f.is_all());
221 assert!(!PacketFilter::all().without(5).contains(5));
222 }
223}