aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-16 23:33:06 -0600
committermat <github@matdoes.dev>2021-12-16 23:33:06 -0600
commitc4eecaf13a4f8f0a81dc278078727df23caa8411 (patch)
tree5082f54d1a9242281d80c250e587235a3ac3755b /azalea-protocol
parent1dc56b6f519f386b6e0b5eac47a84576cedbbb33 (diff)
downloadazalea-drasl-c4eecaf13a4f8f0a81dc278078727df23caa8411.tar.xz
try to implement compression
Diffstat (limited to 'azalea-protocol')
-rw-r--r--azalea-protocol/Cargo.toml1
-rw-r--r--azalea-protocol/src/connect.rs28
-rw-r--r--azalea-protocol/src/mc_buf.rs22
-rw-r--r--azalea-protocol/src/packets/game/ClientboundLoginPacket.rs53
-rw-r--r--azalea-protocol/src/packets/game/mod.rs2
-rw-r--r--azalea-protocol/src/packets/handshake/client_intention_packet.rs2
-rw-r--r--azalea-protocol/src/packets/handshake/mod.rs2
-rw-r--r--azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs2
-rw-r--r--azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs2
-rw-r--r--azalea-protocol/src/packets/login/clientbound_hello_packet.rs2
-rw-r--r--azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs2
-rw-r--r--azalea-protocol/src/packets/login/mod.rs2
-rw-r--r--azalea-protocol/src/packets/login/serverbound_hello_packet.rs2
-rw-r--r--azalea-protocol/src/packets/mod.rs101
-rw-r--r--azalea-protocol/src/packets/status/clientbound_status_response_packet.rs2
-rw-r--r--azalea-protocol/src/packets/status/mod.rs2
-rw-r--r--azalea-protocol/src/packets/status/serverbound_status_request_packet.rs2
-rw-r--r--azalea-protocol/src/read.rs70
18 files changed, 175 insertions, 124 deletions
diff --git a/azalea-protocol/Cargo.toml b/azalea-protocol/Cargo.toml
index 9b5c3c07..272816e2 100644
--- a/azalea-protocol/Cargo.toml
+++ b/azalea-protocol/Cargo.toml
@@ -6,6 +6,7 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+async-compression = {version = "^0.3.8", features = ["tokio", "zlib"]}
async-recursion = "^0.3.2"
async-trait = "0.1.51"
azalea-auth = {path = "../azalea-auth"}
diff --git a/azalea-protocol/src/connect.rs b/azalea-protocol/src/connect.rs
index f6dd9fe7..cc06eec3 100644
--- a/azalea-protocol/src/connect.rs
+++ b/azalea-protocol/src/connect.rs
@@ -24,6 +24,7 @@ pub struct GameConnection {
pub flow: PacketFlow,
/// The buffered writer
pub stream: TcpStream,
+ pub compression_threshold: Option<u32>,
}
pub struct StatusConnection {
@@ -36,6 +37,7 @@ pub struct LoginConnection {
pub flow: PacketFlow,
/// The buffered writer
pub stream: TcpStream,
+ pub compression_threshold: Option<u32>,
}
impl HandshakeConnection {
@@ -62,6 +64,7 @@ impl HandshakeConnection {
LoginConnection {
flow: self.flow,
stream: self.stream,
+ compression_threshold: None,
}
}
@@ -73,7 +76,7 @@ impl HandshakeConnection {
}
pub async fn read(&mut self) -> Result<HandshakePacket, String> {
- read_packet::<HandshakePacket>(&self.flow, &mut self.stream).await
+ read_packet::<HandshakePacket>(&self.flow, &mut self.stream, None).await
}
/// Write a packet to the server
@@ -84,7 +87,7 @@ impl HandshakeConnection {
impl GameConnection {
pub async fn read(&mut self) -> Result<GamePacket, String> {
- read_packet::<GamePacket>(&self.flow, &mut self.stream).await
+ read_packet::<GamePacket>(&self.flow, &mut self.stream, self.compression_threshold).await
}
/// Write a packet to the server
@@ -95,7 +98,7 @@ impl GameConnection {
impl StatusConnection {
pub async fn read(&mut self) -> Result<StatusPacket, String> {
- read_packet::<StatusPacket>(&self.flow, &mut self.stream).await
+ read_packet::<StatusPacket>(&self.flow, &mut self.stream, None).await
}
/// Write a packet to the server
@@ -106,11 +109,28 @@ impl StatusConnection {
impl LoginConnection {
pub async fn read(&mut self) -> Result<LoginPacket, String> {
- read_packet::<LoginPacket>(&self.flow, &mut self.stream).await
+ read_packet::<LoginPacket>(&self.flow, &mut self.stream, self.compression_threshold).await
}
/// Write a packet to the server
pub async fn write(&mut self, packet: LoginPacket) {
write_packet(packet, &mut self.stream).await;
}
+
+ pub fn set_compression_threshold(&mut self, threshold: i32) {
+ // if you pass a threshold of 0 or less, compression is disabled
+ if threshold > 0 {
+ self.compression_threshold = Some(threshold as u32);
+ } else {
+ self.compression_threshold = None;
+ }
+ }
+
+ pub fn game(self) -> GameConnection {
+ GameConnection {
+ flow: self.flow,
+ stream: self.stream,
+ compression_threshold: self.compression_threshold,
+ }
+ }
}
diff --git a/azalea-protocol/src/mc_buf.rs b/azalea-protocol/src/mc_buf.rs
index 0a47f637..84c602ec 100644
--- a/azalea-protocol/src/mc_buf.rs
+++ b/azalea-protocol/src/mc_buf.rs
@@ -134,6 +134,8 @@ impl Writable for Vec<u8> {
pub trait Readable {
async fn read_int_id_list(&mut self) -> Result<Vec<i32>, String>;
async fn read_varint(&mut self) -> Result<i32, String>;
+ fn get_varint_size(&mut self, value: i32) -> u8;
+ fn get_varlong_size(&mut self, value: i32) -> u8;
async fn read_byte_array(&mut self) -> Result<Vec<u8>, String>;
async fn read_bytes(&mut self, n: usize) -> Result<Vec<u8>, String>;
async fn read_utf(&mut self) -> Result<String, String>;
@@ -173,6 +175,26 @@ where
Ok(ans)
}
+ fn get_varint_size(&mut self, value: i32) -> u8 {
+ for i in 1..5 {
+ if (value & -1 << i * 7) != 0 {
+ continue;
+ }
+ return i;
+ }
+ return 5;
+ }
+
+ fn get_varlong_size(&mut self, value: i32) -> u8 {
+ for i in 1..10 {
+ if (value & -1 << i * 7) != 0 {
+ continue;
+ }
+ return i;
+ }
+ return 10;
+ }
+
async fn read_byte_array(&mut self) -> Result<Vec<u8>, String> {
let length = self.read_varint().await? as usize;
Ok(self.read_bytes(length).await?)
diff --git a/azalea-protocol/src/packets/game/ClientboundLoginPacket.rs b/azalea-protocol/src/packets/game/ClientboundLoginPacket.rs
new file mode 100644
index 00000000..ec869faa
--- /dev/null
+++ b/azalea-protocol/src/packets/game/ClientboundLoginPacket.rs
@@ -0,0 +1,53 @@
+use super::GamePacket;
+use crate::mc_buf::{Readable, Writable};
+use azalea_core::resource_location::ResourceLocation;
+use std::hash::Hash;
+use tokio::io::BufReader;
+
+#[derive(Hash, Clone, Debug)]
+pub struct ClientboundLoginPacket {
+ // private final int playerId;
+ // private final boolean hardcore;
+ // private final GameType gameType;
+ // @Nullable
+ // private final GameType previousGameType;
+ // private final Set<ResourceKey<Level>> levels;
+ // private final RegistryAccess.RegistryHolder registryHolder;
+ // private final DimensionType dimensionType;
+ // private final ResourceKey<Level> dimension;
+ // private final long seed;
+ // private final int maxPlayers;
+ // private final int chunkRadius;
+ // private final int simulationDistance;
+ // private final boolean reducedDebugInfo;
+ // private final boolean showDeathScreen;
+ // private final boolean isDebug;
+ // private final boolean isFlat;
+
+}
+
+impl ClientboundLoginPacket {
+ pub fn get(self) -> GamePacket {
+ GamePacket::ClientboundLoginPacket(self)
+ }
+
+ pub fn write(&self, buf: &mut Vec<u8>) {
+ buf.write_varint(self.transaction_id as i32).unwrap();
+ buf.write_utf(self.identifier.to_string().as_str()).unwrap();
+ buf.write_bytes(&self.data).unwrap();
+ }
+
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ buf: &mut T,
+ ) -> Result<GamePacket, String> {
+ let transaction_id = buf.read_varint().await? as u32;
+ let identifier = ResourceLocation::new(&buf.read_utf().await?)?;
+ let data = buf.read_bytes(1048576).await?;
+ Ok(ClientboundLoginPacket {
+ transaction_id,
+ identifier,
+ data,
+ }
+ .get())
+ }
+}
diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs
index a3ef2541..0391a6b1 100644
--- a/azalea-protocol/src/packets/game/mod.rs
+++ b/azalea-protocol/src/packets/game/mod.rs
@@ -22,7 +22,7 @@ impl ProtocolPacket for GamePacket {
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
_id: u32,
flow: &PacketFlow,
- _buf: &mut BufReader<T>,
+ _buf: &mut T,
) -> Result<GamePacket, String>
where
Self: Sized,
diff --git a/azalea-protocol/src/packets/handshake/client_intention_packet.rs b/azalea-protocol/src/packets/handshake/client_intention_packet.rs
index 868626b3..5b50c7cc 100644
--- a/azalea-protocol/src/packets/handshake/client_intention_packet.rs
+++ b/azalea-protocol/src/packets/handshake/client_intention_packet.rs
@@ -28,7 +28,7 @@ impl ClientIntentionPacket {
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- _buf: &mut BufReader<T>,
+ _buf: &mut T,
) -> Result<HandshakePacket, String> {
Err("ClientIntentionPacket::parse not implemented".to_string())
// Ok(ClientIntentionPacket {}.get())
diff --git a/azalea-protocol/src/packets/handshake/mod.rs b/azalea-protocol/src/packets/handshake/mod.rs
index 01010e1e..70e1a90d 100644
--- a/azalea-protocol/src/packets/handshake/mod.rs
+++ b/azalea-protocol/src/packets/handshake/mod.rs
@@ -33,7 +33,7 @@ impl ProtocolPacket for HandshakePacket {
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
id: u32,
flow: &PacketFlow,
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<HandshakePacket, String>
where
Self: Sized,
diff --git a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
index 2c66bfa3..ed9820ef 100644
--- a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
@@ -23,7 +23,7 @@ impl ClientboundCustomQueryPacket {
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<LoginPacket, String> {
let transaction_id = buf.read_varint().await? as u32;
let identifier = ResourceLocation::new(&buf.read_utf().await?)?;
diff --git a/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs b/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs
index 04ba5369..da51f115 100644
--- a/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs
@@ -23,7 +23,7 @@ impl ClientboundGameProfilePacket {
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<LoginPacket, String> {
let uuid = Uuid::from_int_array([
buf.read_int().await? as u32,
diff --git a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
index 36a48706..46ca1301 100644
--- a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
@@ -22,7 +22,7 @@ impl ClientboundHelloPacket {
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<LoginPacket, String> {
let server_id = buf.read_utf_with_len(20).await?;
let public_key = buf.read_byte_array().await?;
diff --git a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs b/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs
index 53c6c9e1..e5009985 100644
--- a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs
@@ -20,7 +20,7 @@ impl ClientboundLoginCompressionPacket {
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<LoginPacket, String> {
let compression_threshold = buf.read_varint().await?;
diff --git a/azalea-protocol/src/packets/login/mod.rs b/azalea-protocol/src/packets/login/mod.rs
index 7fee684a..377a285a 100644
--- a/azalea-protocol/src/packets/login/mod.rs
+++ b/azalea-protocol/src/packets/login/mod.rs
@@ -51,7 +51,7 @@ impl ProtocolPacket for LoginPacket {
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
id: u32,
flow: &PacketFlow,
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<LoginPacket, String>
where
Self: Sized,
diff --git a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
index 32a6dadc..011cc590 100644
--- a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
+++ b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
@@ -20,7 +20,7 @@ impl ServerboundHelloPacket {
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- _buf: &mut BufReader<T>,
+ _buf: &mut T,
) -> Result<LoginPacket, String> {
Err("ServerboundHelloPacket::read not implemented".to_string())
}
diff --git a/azalea-protocol/src/packets/mod.rs b/azalea-protocol/src/packets/mod.rs
index a074b570..08c94509 100644
--- a/azalea-protocol/src/packets/mod.rs
+++ b/azalea-protocol/src/packets/mod.rs
@@ -38,109 +38,10 @@ where
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
id: u32,
flow: &PacketFlow,
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<Self, String>
where
Self: Sized;
fn write(&self, buf: &mut Vec<u8>);
}
-
-// impl Packet {
-// fn get_inner_packet(&self) -> &dyn PacketTrait {
-// match self {
-// Packet::ClientIntentionPacket(packet) => packet,
-// Packet::ServerboundStatusRequestPacket(packet) => packet,
-// Packet::ClientboundStatusResponsePacket(packet) => packet,
-// Packet::ServerboundHelloPacket(packet) => packet,
-// Packet::ClientboundHelloPacket(packet) => packet,
-// }
-// }
-
-// pub fn id(&self) -> u32 {
-// match self {
-// Packet::ClientIntentionPacket(_packet) => 0x00,
-// Packet::ServerboundStatusRequestPacket(_packet) => 0x00,
-// Packet::ClientboundStatusResponsePacket(_packet) => 0x00,
-// Packet::ServerboundHelloPacket(_packet) => 0x00,
-// Packet::ClientboundHelloPacket(_packet) => 0x01,
-// }
-// }
-
-// /// Read a packet by its id, ConnectionProtocol, and flow
-// pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
-// id: u32,
-// protocol: &ConnectionProtocol,
-// flow: &PacketFlow,
-// buf: &mut BufReader<T>,
-// ) -> Result<Packet, String> {
-// match protocol {
-// ConnectionProtocol::Handshake => match flow {
-// PacketFlow::ClientToServer => match id {
-// 0x00 => Ok(
-// handshake::client_intention_packet::ClientIntentionPacket::read(buf).await?,
-// ),
-// _ => Err(format!("Unknown ClientToServer handshake packet id: {}", id)),
-// }
-// PacketFlow::ServerToClient => Err("ServerToClient handshake packets not implemented".to_string()),
-// },
-
-// ConnectionProtocol::Game => Err("Game protocol not implemented yet".to_string()),
-
-// ConnectionProtocol::Status => match flow {
-// PacketFlow::ServerToClient => match id {
-// 0x00 => Ok(
-// status::clientbound_status_response_packet::ClientboundStatusResponsePacket
-// ::read(buf)
-// .await?,
-// ),
-// _ => Err(format!("Unknown ServerToClient status packet id: {}", id)),
-// },
-// PacketFlow::ClientToServer => match id {
-// 0x00 => Ok(
-// status::serverbound_status_request_packet::ServerboundStatusRequestPacket
-// ::read(buf)
-// .await?,
-// ),
-// _ => Err(format!("Unknown ClientToServer status packet id: {}", id)),
-// },
-// },
-
-// ConnectionProtocol::Login => match flow {
-// PacketFlow::ServerToClient => match id {
-// 0x01 => Ok(
-// login::clientbound_hello_packet::ClientboundHelloPacket::read(buf).await?,
-// ),
-// _ => Err(format!("Unknown ServerToClient login packet id: {}", id)),
-// },
-// PacketFlow::ClientToServer => match id {
-// 0x00 => Ok(
-// login::serverbound_hello_packet::ServerboundHelloPacket::read(buf).await?,
-// ),
-// _ => Err(format!("Unknown ClientToServer login packet id: {}", id)),
-// },
-// },
-// }
-// }
-
-// pub fn write(&self, buf: &mut Vec<u8>) {
-// self.get_inner_packet().write(buf);
-// }
-// }
-
-// #[async_trait]
-// pub trait PacketTrait
-// where
-// Self: Sized,
-// {
-// /// Return a version of the packet that you can actually use for stuff
-// fn get(self) -> dyn ProtocolPacket;
-
-// fn write(&self, buf: &mut Vec<u8>);
-
-// async fn read<T: AsyncRead + std::marker::Unpin + std::marker::Send, P: ProtocolPacket>(
-// buf: &mut BufReader<T>,
-// ) -> Result<P, String>
-// where
-// Self: Sized;
-// }
diff --git a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
index 1d8a3aa4..35f913ff 100644
--- a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
+++ b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
@@ -43,7 +43,7 @@ impl ClientboundStatusResponsePacket {
pub fn write(&self, _buf: &mut Vec<u8>) {}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<StatusPacket, String> {
let status_string = buf.read_utf().await?;
let status_json: Value =
diff --git a/azalea-protocol/src/packets/status/mod.rs b/azalea-protocol/src/packets/status/mod.rs
index ac6a34e1..9531111a 100644
--- a/azalea-protocol/src/packets/status/mod.rs
+++ b/azalea-protocol/src/packets/status/mod.rs
@@ -41,7 +41,7 @@ impl ProtocolPacket for StatusPacket {
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
id: u32,
flow: &PacketFlow,
- buf: &mut BufReader<T>,
+ buf: &mut T,
) -> Result<StatusPacket, String>
where
Self: Sized,
diff --git a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
index 6a58da1f..dce9b93a 100644
--- a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
+++ b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
@@ -16,7 +16,7 @@ impl ServerboundStatusRequestPacket {
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- _buf: &mut BufReader<T>,
+ _buf: &mut T,
) -> Result<StatusPacket, String> {
Err("ServerboundStatusRequestPacket::read not implemented".to_string())
}
diff --git a/azalea-protocol/src/read.rs b/azalea-protocol/src/read.rs
index 704774b8..3e63ccc6 100644
--- a/azalea-protocol/src/read.rs
+++ b/azalea-protocol/src/read.rs
@@ -1,10 +1,14 @@
-use tokio::{io::BufReader, net::TcpStream};
-
use crate::{connect::PacketFlow, mc_buf::Readable, packets::ProtocolPacket};
+use async_compression::tokio::bufread::ZlibDecoder;
+use tokio::{
+ io::{AsyncReadExt, BufReader},
+ net::TcpStream,
+};
pub async fn read_packet<P: ProtocolPacket>(
flow: &PacketFlow,
stream: &mut TcpStream,
+ compression_threshold: Option<u32>,
) -> Result<P, String> {
// what this does:
// 1. reads the first 5 bytes, probably only some of this will be used to get the packet length
@@ -15,14 +19,64 @@ pub async fn read_packet<P: ProtocolPacket>(
// the first thing minecraft sends us is the length as a varint, which can be up to 5 bytes long
let mut buf = BufReader::with_capacity(4 * 1024 * 1024, stream);
- let _packet_size = buf.read_varint().await?;
+ // Packet Length
+ let packet_size = buf.read_varint().await?;
+
+ // if there's no compression, we can just read the rest of the packet normally
+ if compression_threshold.is_none() {
+ // then, minecraft tells us the packet id as a varint
+ let packet_id = buf.read_varint().await?;
+
+ // if we recognize the packet id, parse it
+
+ println!("reading uncompressed packet id: {}", packet_id);
+ let packet = P::read(packet_id.try_into().unwrap(), flow, &mut buf).await?;
+
+ return Ok(packet);
+ }
+
+ println!("compressed packet size: {}", packet_size);
+
+ // there's compression
+ // Data Length
+ let data_size = buf.read_varint().await?;
+ println!("data size: {}", data_size);
+
+ // this packet has no compression
+ if data_size == 0 {
+ // Packet ID
+ let packet_id = buf.read_varint().await?;
+ println!(
+ "reading compressed packet without compression packet id: {}",
+ packet_id
+ );
+ let packet = P::read(packet_id.try_into().unwrap(), flow, &mut buf).await?;
+ return Ok(packet);
+ }
+
+ // this packet has compression
+ let packet_size_varint_size = buf.get_varint_size(packet_size);
+
+ let mut compressed_data = vec![0; packet_size as usize - packet_size_varint_size as usize];
+ buf.read_exact(compressed_data.as_mut_slice())
+ .await
+ .expect("Not enough compressed data");
- // then, minecraft tells us the packet id as a varint
- let packet_id = buf.read_varint().await?;
+ let mut z = ZlibDecoder::new(compressed_data.as_slice());
- // if we recognize the packet id, parse it
+ // Packet ID
+ let packet_id = z.read_varint().await.unwrap();
+ println!("reading compressed packet id: {}", packet_id);
- let packet = P::read(packet_id.try_into().unwrap(), flow, &mut buf).await?;
+ if let Ok(packet) = P::read(packet_id as u32, flow, &mut z).await {
+ Ok(packet)
+ } else {
+ // read the rest of the bytes
+ let packet_id_varint_size = z.get_varint_size(packet_id);
+ let mut buf = vec![0; packet_size as usize - packet_id_varint_size as usize];
+ z.read_exact(buf.as_mut_slice()).await.unwrap();
+ println!("{:?}", buf);
- Ok(packet)
+ Err(format!("Error on packet id: {}", packet_id))
+ }
}