Skip to content

Commit 39fc57b

Browse files
committed
add compression
1 parent 7a3d14b commit 39fc57b

22 files changed

Lines changed: 140 additions & 85 deletions

src/net/packet.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ mod packets {
66
}
77

88
use tokio::io::AsyncReadExt;
9+
use std::io::Write;
910

10-
use crate::net::codec::read_var;
11+
use crate::net::codec::{read_var, write_var};
1112

1213
pub enum ClientPacket {
1314
// status state
@@ -35,13 +36,58 @@ pub enum ProtocolState {
3536
Play
3637
}
3738

38-
pub async fn read_packet<R: AsyncReadExt + Unpin>(stream: &mut R, state: &ProtocolState) -> anyhow::Result<Option<ClientPacket>> {
39+
pub fn encode_packet(data: &[u8]) -> Vec<u8> {
40+
let mut result = Vec::new();
41+
42+
if data.len() > 256 {
43+
let uncompressed_len = data.len();
44+
45+
let mut encoder = flate2::write::ZlibEncoder::new(Vec::new(), flate2::Compression::fast());
46+
encoder.write_all(&data).unwrap();
47+
48+
let compressed = encoder.finish().unwrap();
49+
50+
let mut inner = Vec::with_capacity(5 + compressed.len());
51+
write_var(&mut inner, uncompressed_len as i32).unwrap();
52+
inner.extend_from_slice(&compressed);
53+
54+
write_var(&mut result, inner.len() as i32).unwrap();
55+
result.extend_from_slice(&inner);
56+
} else {
57+
let mut inner = Vec::with_capacity(5);
58+
write_var(&mut inner, 0).unwrap();
59+
inner.extend_from_slice(&data);
60+
61+
write_var(&mut result, inner.len() as i32).unwrap();
62+
result.extend_from_slice(&inner);
63+
}
64+
65+
result
66+
}
67+
68+
pub async fn read_packet<R: AsyncReadExt + Unpin>(stream: &mut R, state: &ProtocolState, compression: bool) -> anyhow::Result<Option<ClientPacket>> {
3969
let packet_len = read_var(stream).await.map_err(|e| anyhow::anyhow!("Failed to read packet length: {}", e))?;
4070

4171
let mut packet_buf = vec![0u8; packet_len as usize];
4272
stream.read_exact(&mut packet_buf).await.map_err(|e| anyhow::anyhow!("Failed to read packet data: {}", e))?;
4373

4474
let mut cursor = std::io::Cursor::new(packet_buf);
75+
76+
if compression {
77+
let data_len = read_var(&mut cursor).await.map_err(|e| anyhow::anyhow!("Failed to read data length: {}", e))?;
78+
79+
if data_len != 0 {
80+
let mut compressed = Vec::new();
81+
std::io::Read::read_to_end(&mut cursor, &mut compressed).map_err(|e| anyhow::anyhow!("Failed to read compressed data: {}", e))?;
82+
83+
let mut decoder = flate2::read::ZlibDecoder::new(&compressed[..]);
84+
let mut decompressed = Vec::with_capacity(data_len as usize);
85+
std::io::Read::read_to_end(&mut decoder, &mut decompressed).map_err(|e| anyhow::anyhow!("Failed to decompress data: {}", e))?;
86+
87+
cursor = std::io::Cursor::new(decompressed);
88+
}
89+
}
90+
4591
let packet_id = read_var(&mut cursor).await.map_err(|e| anyhow::anyhow!("Failed to read packet ID: {}", e))?;
4692

4793
if packet_id != 0x0C && packet_id != 0x1D { // these packets are spammy

src/net/packets/clientbound/chunk_data_with_light.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ pub async fn send_chunk_data_with_light<W: tokio::io::AsyncWriteExt + Unpin>(
6666
packet_data.extend_from_slice(&FULLBRIGHT_ENTRY);
6767
}
6868

69-
let mut len_prefix = Vec::with_capacity(5);
70-
write_var(&mut len_prefix, packet_data.len() as i32)?;
71-
72-
stream.write_all(&len_prefix).await?;
7369
stream.write_all(&packet_data).await?;
7470
stream.flush().await?;
7571

src/net/packets/clientbound/finish_configuration.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ use crate::net::codec::write_var;
33
pub async fn send_finish_configuration<W: tokio::io::AsyncWriteExt + Unpin>(stream: &mut W) -> anyhow::Result<()> {
44
let packet_data = vec![crate::net::packet::configuration::clientbound::FINISH_CONFIGURATION as u8];
55

6-
let mut len_prefix = Vec::with_capacity(5);
7-
write_var(&mut len_prefix, packet_data.len() as i32)?;
8-
9-
stream.write_all(&len_prefix).await?;
106
stream.write_all(&packet_data).await?;
117
stream.flush().await?;
128

src/net/packets/clientbound/game_event.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ pub async fn send_game_event<W: tokio::io::AsyncWriteExt + Unpin>(stream: &mut W
77
packet_data.push(event);
88
packet_data.write_f32(value).await?;
99

10-
let mut len_prefix = Vec::with_capacity(5);
11-
write_var(&mut len_prefix, packet_data.len() as i32)?;
12-
13-
stream.write_all(&len_prefix).await?;
1410
stream.write_all(&packet_data).await?;
1511
stream.flush().await?;
1612

src/net/packets/clientbound/keep_alive.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ pub async fn send_keep_alive<W: tokio::io::AsyncWriteExt + Unpin>(stream: &mut W
77
let ms = chrono::Utc::now().timestamp_millis();
88
packet_data.write_i64(ms).await?;
99

10-
let mut len_prefix = Vec::with_capacity(5);
11-
write_var(&mut len_prefix, packet_data.len() as i32)?;
12-
13-
stream.write_all(&len_prefix).await?;
1410
stream.write_all(&packet_data).await?;
1511
stream.flush().await?;
1612

src/net/packets/clientbound/known_packs.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ pub async fn send_known_packs<W: tokio::io::AsyncWriteExt + Unpin>(stream: &mut
1414
write_var(&mut packet_data, "1.21".len() as i32)?;
1515
packet_data.extend_from_slice("1.21".as_bytes());
1616

17-
let mut len_prefix = Vec::with_capacity(5);
18-
write_var(&mut len_prefix, packet_data.len() as i32)?;
19-
20-
stream.write_all(&len_prefix).await?;
2117
stream.write_all(&packet_data).await?;
2218
stream.flush().await?;
2319

src/net/packets/clientbound/login_play.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ pub async fn send_login_play<W: tokio::io::AsyncWriteExt + Unpin>(stream: &mut W
3636
write_var(&mut packet_data, 62)?; // sea level
3737
packet_data.push(false as u8); // enforce secure chat
3838

39-
let mut len_prefix = Vec::with_capacity(5);
40-
write_var(&mut len_prefix, packet_data.len() as i32)?;
41-
42-
stream.write_all(&len_prefix).await?;
4339
stream.write_all(&packet_data).await?;
4440
stream.flush().await?;
4541

src/net/packets/clientbound/login_success.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@ pub async fn send_login_success<W: tokio::io::AsyncWriteExt + Unpin>(stream: &mu
3939
}
4040
}
4141

42-
let mut len_prefix = Vec::with_capacity(5);
43-
write_var(&mut len_prefix, packet_data.len() as i32)?;
44-
45-
stream.write_all(&len_prefix).await?;
4642
stream.write_all(&packet_data).await?;
4743
stream.flush().await?;
4844

src/net/packets/clientbound/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ pub mod plugin_message;
1515
pub mod set_center_chunk;
1616
pub mod chunk_data_with_light;
1717
pub mod player_info_remove;
18-
pub mod player_chat_message;
18+
pub mod player_chat_message;
19+
pub mod set_compression;

src/net/packets/clientbound/player_chat_message.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ pub async fn send_player_chat_message<W: tokio::io::AsyncWriteExt + Unpin>(
6464

6565
packet_data.write_u8(0)?; // no target name
6666

67-
let mut len_prefix = Vec::with_capacity(5);
68-
write_var(&mut len_prefix, packet_data.len() as i32)?;
69-
70-
stream.write_all(&len_prefix).await?;
7167
stream.write_all(&packet_data).await?;
7268
stream.flush().await?;
7369

0 commit comments

Comments
 (0)