1use anyhow::{bail, Result};
2use std::{
3 io::{self, Read, Write},
4 vec,
5};
6mod builder;
7pub mod raw;
8pub mod types;
9use crate::types::*;
10use flate2::{
11 bufread::{ZlibDecoder, ZlibEncoder},
12 Compression,
13};
14
15pub trait Encoder: Sized {
16 fn write_to(&self, w: &mut impl io::Write) -> Result<()>;
17}
18
19impl<'a, T> Encoder for &'a T
20where
21 T: Encoder,
22{
23 fn write_to(&self, w: &mut impl io::Write) -> Result<()> {
24 T::write_to(*self, w)
25 }
26}
27pub trait Decoder: Sized {
28 fn read_from(r: &mut impl io::Read) -> Result<Self>;
29}
30
31pub trait Packet: Encoder + Decoder {
32 const ID: VarInt;
33 fn encode(&self) -> Result<RawPacket> {
34 let mut buf = Vec::new();
35 self.write_to(&mut buf)?;
36 Ok(RawPacket {
37 id: Self::ID,
38 data: buf,
39 })
40 }
41
42 fn decode(raw: RawPacket) -> Result<Self> {
43 let mut buf = raw.data.as_slice();
44 Self::read_from(&mut buf)
45 }
46}
47
48#[derive(Debug)]
49pub struct RawPacket {
50 pub id: VarInt,
51 pub data: Vec<u8>,
52}
53
54impl io::Write for RawPacket {
55 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
56 self.data.write(buf)
57 }
58
59 fn flush(&mut self) -> io::Result<()> {
60 self.data.flush()
61 }
62}
63
64impl RawPacket {
65 pub fn unpack(r: &mut impl io::Read, threshold: i32) -> Result<Self> {
66 if threshold >= 0 {
67 Self::unpack_with_compression(r, threshold)
68 } else {
69 Self::unpack_without_compression(r)
70 }
71 }
72
73 fn unpack_without_compression(r: &mut impl io::Read) -> Result<Self> {
74 let len = VarInt::read_from(r)?.0 as usize;
75 let mut buf = vec![0; len];
76 r.read_exact(&mut buf)?;
77
78 let mut buf = buf.as_slice();
79 let id = VarInt::read_from(&mut buf)?;
80
81 Ok(Self {
82 id,
83 data: buf.to_vec(),
84 })
85 }
86
87 fn unpack_with_compression(r: &mut impl io::Read, threshold: i32) -> Result<Self> {
88 let pk_len = VarInt::read_from(r)?.0 as usize;
89 let mut buf = vec![0u8; pk_len];
90 r.read_exact(&mut buf)?;
91 let mut buf = buf.as_slice();
92 let data_len = VarInt::read_from(&mut buf)?.0;
93
94 let id: VarInt;
95
96 let data: Vec<u8>;
97
98 if data_len != 0 {
99 if data_len < threshold {
100 bail!(
101 "data length is smaller than threshold: {} < {}",
102 data_len,
103 threshold
104 );
105 }
106
107 if data_len > 2097152 {
108 bail!(
109 "data length is larger than protocol maximum: {} > {}",
110 data_len,
111 2097152
112 );
113 }
114
115 let mut decoder = ZlibDecoder::new(&buf[..]);
116 let buf = &mut Vec::new();
117
118 decoder.read_to_end(buf)?;
119
120 let mut buf = buf.as_slice();
121
122 id = VarInt::read_from(&mut buf)?;
123
124 data = buf.to_vec();
125 } else {
126 id = VarInt::read_from(&mut buf)?;
127
128 data = buf.to_vec();
129 }
130
131 Ok(Self { id, data })
132 }
133
134 pub fn pack(&mut self, w: &mut impl io::Write, threshold: i32) -> Result<()> {
135 if threshold >= 0 {
136 self.pack_with_compression(w, threshold)
137 } else {
138 self.pack_without_compression(w)
139 }
140 }
141
142 fn pack_with_compression(&mut self, w: &mut impl io::Write, threshold: i32) -> Result<()> {
143 let mut buf = Vec::new();
144 self.id.write_to(&mut buf)?;
145 buf.write_all(&self.data)?;
146 let data_len = buf.len();
147
148 if data_len < threshold as usize {
149 let mut buf2 = Vec::new();
150 VarInt(0).write_to(&mut buf2)?;
151 buf2.write_all(&buf)?;
152 VarInt(buf2.len() as i32).write_to(w)?;
153 w.write_all(&buf2)?;
154 } else {
155 let mut encoder = ZlibEncoder::new(buf.as_slice(), Compression::default());
156 let mut buf2 = Vec::new();
157 VarInt(data_len as i32).write_to(&mut buf2)?;
158 encoder.read_to_end(&mut buf2)?;
159 VarInt(buf2.len() as i32).write_to(w)?;
160 w.write_all(&buf2)?;
161 }
162
163 Ok(())
185 }
186
187 fn pack_without_compression(&self, w: &mut impl io::Write) -> Result<()> {
188 let buf = &mut Vec::new();
189
190 self.id.write_to(buf)?;
191 buf.write_all(self.data.as_slice())?;
192
193 VarInt(buf.len() as i32).write_to(w)?;
194
195 w.write_all(buf.as_slice())?;
196
197 Ok(())
198 }
199}