mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 23:44:38 +00:00
writing compressed packets
This commit is contained in:
parent
493aae582a
commit
498077e09f
3 changed files with 67 additions and 34 deletions
|
@ -81,7 +81,7 @@ impl HandshakeConnection {
|
||||||
|
|
||||||
/// Write a packet to the server
|
/// Write a packet to the server
|
||||||
pub async fn write(&mut self, packet: HandshakePacket) {
|
pub async fn write(&mut self, packet: HandshakePacket) {
|
||||||
write_packet(packet, &mut self.stream).await;
|
write_packet(packet, &mut self.stream, None).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ impl GameConnection {
|
||||||
|
|
||||||
/// Write a packet to the server
|
/// Write a packet to the server
|
||||||
pub async fn write(&mut self, packet: GamePacket) {
|
pub async fn write(&mut self, packet: GamePacket) {
|
||||||
write_packet(packet, &mut self.stream).await;
|
write_packet(packet, &mut self.stream, self.compression_threshold).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ impl StatusConnection {
|
||||||
|
|
||||||
/// Write a packet to the server
|
/// Write a packet to the server
|
||||||
pub async fn write(&mut self, packet: StatusPacket) {
|
pub async fn write(&mut self, packet: StatusPacket) {
|
||||||
write_packet(packet, &mut self.stream).await;
|
write_packet(packet, &mut self.stream, None).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ impl LoginConnection {
|
||||||
|
|
||||||
/// Write a packet to the server
|
/// Write a packet to the server
|
||||||
pub async fn write(&mut self, packet: LoginPacket) {
|
pub async fn write(&mut self, packet: LoginPacket) {
|
||||||
write_packet(packet, &mut self.stream).await;
|
write_packet(packet, &mut self.stream, self.compression_threshold).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_compression_threshold(&mut self, threshold: i32) {
|
pub fn set_compression_threshold(&mut self, threshold: i32) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ where
|
||||||
// this is always true in multiplayer, false in singleplayer
|
// this is always true in multiplayer, false in singleplayer
|
||||||
static VALIDATE_DECOMPRESSED: bool = true;
|
static VALIDATE_DECOMPRESSED: bool = true;
|
||||||
|
|
||||||
static MAXIMUM_UNCOMPRESSED_LENGTH: u32 = 8388608;
|
pub static MAXIMUM_UNCOMPRESSED_LENGTH: u32 = 8388608;
|
||||||
|
|
||||||
async fn compression_decoder<R>(
|
async fn compression_decoder<R>(
|
||||||
stream: &mut R,
|
stream: &mut R,
|
||||||
|
@ -102,7 +102,6 @@ where
|
||||||
{
|
{
|
||||||
let mut buf = frame_splitter(stream).await?;
|
let mut buf = frame_splitter(stream).await?;
|
||||||
if let Some(compression_threshold) = compression_threshold {
|
if let Some(compression_threshold) = compression_threshold {
|
||||||
println!("compression_decoder");
|
|
||||||
buf = compression_decoder(&mut buf.as_slice(), compression_threshold).await?;
|
buf = compression_decoder(&mut buf.as_slice(), compression_threshold).await?;
|
||||||
}
|
}
|
||||||
let packet = packet_decoder(&mut buf.as_slice(), flow).await?;
|
let packet = packet_decoder(&mut buf.as_slice(), flow).await?;
|
||||||
|
|
|
@ -1,31 +1,65 @@
|
||||||
use tokio::{io::AsyncWriteExt, net::TcpStream};
|
use std::io::Read;
|
||||||
|
|
||||||
use crate::{mc_buf::Writable, packets::ProtocolPacket};
|
use crate::{mc_buf::Writable, packets::ProtocolPacket, read::MAXIMUM_UNCOMPRESSED_LENGTH};
|
||||||
|
use async_compression::tokio::bufread::ZlibEncoder;
|
||||||
|
use tokio::{
|
||||||
|
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},
|
||||||
|
net::TcpStream,
|
||||||
|
};
|
||||||
|
|
||||||
pub async fn write_packet(packet: impl ProtocolPacket, stream: &mut TcpStream) {
|
fn frame_prepender(data: &mut Vec<u8>) -> Result<Vec<u8>, String> {
|
||||||
// TODO: implement compression
|
let mut buf = Vec::new();
|
||||||
|
buf.write_varint(data.len() as i32)
|
||||||
// packet structure:
|
.map_err(|e| e.to_string())?;
|
||||||
// length (varint) + id (varint) + data
|
buf.append(data);
|
||||||
|
Ok(buf)
|
||||||
// write the packet id
|
}
|
||||||
let mut id_and_data_buf = vec![];
|
|
||||||
id_and_data_buf
|
fn packet_encoder<P: ProtocolPacket + std::fmt::Debug>(packet: &P) -> Result<Vec<u8>, String> {
|
||||||
.write_varint(packet.id() as i32)
|
let mut buf = Vec::new();
|
||||||
.expect("Writing packet id failed");
|
buf.write_varint(packet.id() as i32)
|
||||||
packet.write(&mut id_and_data_buf);
|
.map_err(|e| e.to_string())?;
|
||||||
|
packet.write(&mut buf);
|
||||||
// write the packet data
|
if buf.len() > MAXIMUM_UNCOMPRESSED_LENGTH as usize {
|
||||||
|
return Err(format!(
|
||||||
// make a new buffer that has the length at the beginning
|
"Packet too big (is {} bytes, should be less than {}): {:?}",
|
||||||
// and id+data at the end
|
buf.len(),
|
||||||
let mut complete_buf: Vec<u8> = Vec::new();
|
MAXIMUM_UNCOMPRESSED_LENGTH,
|
||||||
complete_buf
|
packet
|
||||||
.write_varint(id_and_data_buf.len() as i32)
|
));
|
||||||
.expect("Writing packet length failed");
|
}
|
||||||
complete_buf.append(&mut id_and_data_buf);
|
Ok(buf)
|
||||||
|
}
|
||||||
// finally, write and flush to the stream
|
|
||||||
stream.write_all(&complete_buf).await.unwrap();
|
async fn compression_encoder(data: &[u8], compression_threshold: u32) -> Result<Vec<u8>, String> {
|
||||||
stream.flush().await.unwrap();
|
let n = data.len();
|
||||||
|
// if it's less than the compression threshold, don't compress
|
||||||
|
if n < compression_threshold as usize {
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
buf.write_varint(0).map_err(|e| e.to_string())?;
|
||||||
|
buf.write_all(data).await.map_err(|e| e.to_string())?;
|
||||||
|
Ok(buf)
|
||||||
|
} else {
|
||||||
|
// otherwise, compress
|
||||||
|
let mut deflater = ZlibEncoder::new(data);
|
||||||
|
// write deflated data to buf
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
deflater
|
||||||
|
.read_to_end(&mut buf)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn write_packet<P>(packet: P, stream: &mut TcpStream, compression_threshold: Option<u32>)
|
||||||
|
where
|
||||||
|
P: ProtocolPacket + std::fmt::Debug,
|
||||||
|
{
|
||||||
|
let mut buf = packet_encoder(&packet).unwrap();
|
||||||
|
if let Some(threshold) = compression_threshold {
|
||||||
|
buf = compression_encoder(&buf, threshold).await.unwrap();
|
||||||
|
}
|
||||||
|
buf = frame_prepender(&mut buf).unwrap();
|
||||||
|
stream.write_all(&buf).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue