1
0
Fork 0
mirror of https://github.com/italicsjenga/valence.git synced 2025-02-03 17:16:34 +11:00
valence/crates/valence_protocol/src/codec.rs

539 lines
15 KiB
Rust
Raw Normal View History

use std::fmt;
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
use aes::cipher::{AsyncStreamCipher, NewCipher};
use anyhow::{bail, ensure};
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
use bytes::{Buf, BufMut, BytesMut};
use tracing::debug;
2022-04-14 14:55:45 -07:00
use crate::var_int::{VarInt, VarIntDecodeError};
use crate::{DecodePacket, Encode, EncodePacket, Result, MAX_PACKET_SIZE};
2022-04-14 14:55:45 -07:00
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
/// The AES block cipher with a 128 bit key, using the CFB-8 mode of
/// operation.
#[cfg(feature = "encryption")]
type Cipher = cfb8::Cfb8<aes::Aes128>;
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
#[derive(Default)]
pub struct PacketEncoder {
buf: BytesMut,
#[cfg(feature = "compression")]
2022-04-14 14:55:45 -07:00
compress_buf: Vec<u8>,
#[cfg(feature = "compression")]
2022-04-14 14:55:45 -07:00
compression_threshold: Option<u32>,
#[cfg(feature = "encryption")]
2022-04-14 14:55:45 -07:00
cipher: Option<Cipher>,
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
impl PacketEncoder {
pub fn new() -> Self {
Self::default()
2022-04-14 14:55:45 -07:00
}
pub fn append_bytes(&mut self, bytes: &[u8]) {
self.buf.extend_from_slice(bytes)
}
pub fn prepend_packet<P>(&mut self, pkt: &P) -> Result<()>
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
where
P: EncodePacket + ?Sized,
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
{
let start_len = self.buf.len();
self.append_packet(pkt)?;
2022-04-14 14:55:45 -07:00
let end_len = self.buf.len();
let total_packet_len = end_len - start_len;
2022-04-14 14:55:45 -07:00
// 1) Move everything back by the length of the packet.
// 2) Move the packet to the new space at the front.
// 3) Truncate the old packet away.
self.buf.put_bytes(0, total_packet_len);
self.buf.copy_within(..end_len, total_packet_len);
self.buf.copy_within(total_packet_len + start_len.., 0);
self.buf.truncate(end_len);
Ok(())
}
pub fn append_packet<P>(&mut self, pkt: &P) -> Result<()>
where
P: EncodePacket + ?Sized,
{
let start_len = self.buf.len();
pkt.encode_packet((&mut self.buf).writer())?;
let data_len = self.buf.len() - start_len;
#[cfg(feature = "compression")]
2022-04-14 14:55:45 -07:00
if let Some(threshold) = self.compression_threshold {
use std::io::Read;
use flate2::bufread::ZlibEncoder;
use flate2::Compression;
if data_len > threshold as usize {
let mut z = ZlibEncoder::new(&self.buf[start_len..], Compression::new(4));
self.compress_buf.clear();
2022-04-14 14:55:45 -07:00
let data_len_size = VarInt(data_len as i32).written_size();
let packet_len = data_len_size + z.read_to_end(&mut self.compress_buf)?;
2022-04-14 14:55:45 -07:00
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
ensure!(
packet_len <= MAX_PACKET_SIZE as usize,
"packet exceeds maximum length"
);
2022-04-14 14:55:45 -07:00
drop(z);
2022-04-14 14:55:45 -07:00
self.buf.truncate(start_len);
2022-08-05 23:10:25 -07:00
let mut writer = (&mut self.buf).writer();
VarInt(packet_len as i32).encode(&mut writer)?;
VarInt(data_len as i32).encode(&mut writer)?;
self.buf.extend_from_slice(&self.compress_buf);
2022-04-14 14:55:45 -07:00
} else {
let data_len_size = 1;
let packet_len = data_len_size + data_len;
2022-04-14 14:55:45 -07:00
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
ensure!(
packet_len <= MAX_PACKET_SIZE as usize,
"packet exceeds maximum length"
);
2022-08-05 23:10:25 -07:00
let packet_len_size = VarInt(packet_len as i32).written_size();
let data_prefix_len = packet_len_size + data_len_size;
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
self.buf.put_bytes(0, data_prefix_len);
self.buf
.copy_within(start_len..start_len + data_len, start_len + data_prefix_len);
let mut front = &mut self.buf[start_len..];
VarInt(packet_len as i32).encode(&mut front)?;
// Zero for no compression on this packet.
VarInt(0).encode(front)?;
2022-04-14 14:55:45 -07:00
}
return Ok(());
}
2022-04-14 14:55:45 -07:00
let packet_len = data_len;
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
ensure!(
packet_len <= MAX_PACKET_SIZE as usize,
"packet exceeds maximum length"
);
2022-08-05 23:10:25 -07:00
let packet_len_size = VarInt(packet_len as i32).written_size();
self.buf.put_bytes(0, packet_len_size);
self.buf
.copy_within(start_len..start_len + data_len, start_len + packet_len_size);
let front = &mut self.buf[start_len..];
VarInt(packet_len as i32).encode(front)?;
2022-04-14 14:55:45 -07:00
2022-08-05 23:10:25 -07:00
Ok(())
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
/// Takes all the packets written so far and encrypts them if encryption is
/// enabled.
pub fn take(&mut self) -> BytesMut {
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
if let Some(cipher) = &mut self.cipher {
cipher.encrypt(&mut self.buf);
2022-04-14 14:55:45 -07:00
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
self.buf.split()
2022-04-14 14:55:45 -07:00
}
pub fn clear(&mut self) {
self.buf.clear();
}
#[cfg(feature = "compression")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
pub fn set_compression(&mut self, threshold: Option<u32>) {
self.compression_threshold = threshold;
2022-08-05 23:10:25 -07:00
}
/// Encrypts all future packets **and any packets that have
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
/// not been [taken] yet.**
///
/// [taken]: Self::take
#[cfg(feature = "encryption")]
2022-04-14 14:55:45 -07:00
pub fn enable_encryption(&mut self, key: &[u8; 16]) {
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
assert!(self.cipher.is_none(), "encryption is already enabled");
2022-04-14 14:55:45 -07:00
self.cipher = Some(NewCipher::new(key.into(), key.into()));
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
}
2022-04-14 14:55:45 -07:00
pub fn encode_packet<P>(buf: &mut Vec<u8>, pkt: &P) -> Result<()>
where
P: EncodePacket + ?Sized,
{
let start_len = buf.len();
pkt.encode_packet(&mut *buf)?;
let packet_len = buf.len() - start_len;
ensure!(
packet_len <= MAX_PACKET_SIZE as usize,
"packet exceeds maximum length"
);
let packet_len_size = VarInt(packet_len as i32).written_size();
buf.put_bytes(0, packet_len_size);
buf.copy_within(
start_len..start_len + packet_len,
start_len + packet_len_size,
);
let front = &mut buf[start_len..];
VarInt(packet_len as i32).encode(front)?;
Ok(())
}
#[cfg(feature = "compression")]
pub fn encode_packet_compressed<P>(
buf: &mut Vec<u8>,
pkt: &P,
threshold: u32,
scratch: &mut Vec<u8>,
) -> Result<()>
where
P: EncodePacket + ?Sized,
{
use std::io::Read;
use flate2::bufread::ZlibEncoder;
use flate2::Compression;
let start_len = buf.len();
pkt.encode_packet(&mut *buf)?;
let data_len = buf.len() - start_len;
if data_len > threshold as usize {
let mut z = ZlibEncoder::new(&buf[start_len..], Compression::new(4));
scratch.clear();
let data_len_size = VarInt(data_len as i32).written_size();
let packet_len = data_len_size + z.read_to_end(scratch)?;
ensure!(
packet_len <= MAX_PACKET_SIZE as usize,
"packet exceeds maximum length"
);
drop(z);
buf.truncate(start_len);
VarInt(packet_len as i32).encode(&mut *buf)?;
VarInt(data_len as i32).encode(&mut *buf)?;
buf.extend_from_slice(scratch);
} else {
let data_len_size = 1;
let packet_len = data_len_size + data_len;
ensure!(
packet_len <= MAX_PACKET_SIZE as usize,
"packet exceeds maximum length"
);
let packet_len_size = VarInt(packet_len as i32).written_size();
let data_prefix_len = packet_len_size + data_len_size;
buf.put_bytes(0, data_prefix_len);
buf.copy_within(start_len..start_len + data_len, start_len + data_prefix_len);
let mut front = &mut buf[start_len..];
VarInt(packet_len as i32).encode(&mut front)?;
// Zero for no compression on this packet.
VarInt(0).encode(front)?;
}
Ok(())
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
#[derive(Default)]
pub struct PacketDecoder {
buf: BytesMut,
cursor: usize,
#[cfg(feature = "compression")]
2022-04-14 14:55:45 -07:00
decompress_buf: Vec<u8>,
#[cfg(feature = "compression")]
compression_enabled: bool,
#[cfg(feature = "encryption")]
2022-04-14 14:55:45 -07:00
cipher: Option<Cipher>,
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
impl PacketDecoder {
pub fn new() -> Self {
Self::default()
2022-04-14 14:55:45 -07:00
}
pub fn try_next_packet<'a, P>(&'a mut self) -> Result<Option<P>>
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
where
P: DecodePacket<'a> + fmt::Debug,
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
{
self.buf.advance(self.cursor);
self.cursor = 0;
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
let mut r = &self.buf[..];
2022-04-14 14:55:45 -07:00
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
let packet_len = match VarInt::decode_partial(&mut r) {
Ok(len) => len,
Err(VarIntDecodeError::Incomplete) => return Ok(None),
Err(VarIntDecodeError::TooLarge) => bail!("malformed packet length VarInt"),
};
2022-04-14 14:55:45 -07:00
ensure!(
(0..=MAX_PACKET_SIZE).contains(&packet_len),
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
"packet length of {packet_len} is out of bounds"
2022-04-14 14:55:45 -07:00
);
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
if r.len() < packet_len as usize {
return Ok(None);
2022-04-14 14:55:45 -07:00
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
r = &r[..packet_len as usize];
2022-04-14 14:55:45 -07:00
#[cfg(feature = "compression")]
let packet = if self.compression_enabled {
use std::io::Read;
use anyhow::Context;
use flate2::bufread::ZlibDecoder;
use crate::Decode;
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
let data_len = VarInt::decode(&mut r)?.0;
2022-04-14 14:55:45 -07:00
ensure!(
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
(0..MAX_PACKET_SIZE).contains(&data_len),
"decompressed packet length of {data_len} is out of bounds"
2022-04-14 14:55:45 -07:00
);
if data_len != 0 {
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
self.decompress_buf.clear();
self.decompress_buf.reserve_exact(data_len as usize);
let mut z = ZlibDecoder::new(r).take(data_len as u64);
z.read_to_end(&mut self.decompress_buf)
.context("decompressing packet")?;
r = &self.decompress_buf;
P::decode_packet(&mut r)?
2022-04-14 14:55:45 -07:00
} else {
P::decode_packet(&mut r)?
2022-04-14 14:55:45 -07:00
}
} else {
P::decode_packet(&mut r)?
2022-04-14 14:55:45 -07:00
};
#[cfg(not(feature = "compression"))]
let packet = P::decode_packet(&mut r)?;
2022-04-14 14:55:45 -07:00
if !r.is_empty() {
let remaining = r.len();
debug!("packet after partial decode ({remaining} bytes remain): {packet:?}");
bail!("packet contents were not read completely ({remaining} bytes remain)");
}
2022-04-14 14:55:45 -07:00
let total_packet_len = VarInt(packet_len).written_size() + packet_len as usize;
self.cursor = total_packet_len;
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
Ok(Some(packet))
2022-04-14 14:55:45 -07:00
}
pub fn has_next_packet(&self) -> Result<bool> {
let mut r = &self.buf[self.cursor..];
match VarInt::decode_partial(&mut r) {
Ok(packet_len) => {
ensure!(
(0..=MAX_PACKET_SIZE).contains(&packet_len),
"packet length of {packet_len} is out of bounds"
);
Ok(r.len() >= packet_len as usize)
}
Err(VarIntDecodeError::Incomplete) => Ok(false),
Err(VarIntDecodeError::TooLarge) => bail!("malformed packet length VarInt"),
}
}
#[cfg(feature = "compression")]
pub fn set_compression(&mut self, enabled: bool) {
self.compression_enabled = enabled;
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
}
2022-04-14 14:55:45 -07:00
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
pub fn enable_encryption(&mut self, key: &[u8; 16]) {
assert!(self.cipher.is_none(), "encryption is already enabled");
let mut cipher = Cipher::new(key.into(), key.into());
// Don't forget to decrypt the data we already have.
cipher.decrypt(&mut self.buf[self.cursor..]);
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
self.cipher = Some(cipher);
}
pub fn queue_bytes(&mut self, mut bytes: BytesMut) {
#![allow(unused_mut)]
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
if let Some(cipher) = &mut self.cipher {
cipher.decrypt(&mut bytes);
2022-04-14 14:55:45 -07:00
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
self.buf.unsplit(bytes);
2022-04-14 14:55:45 -07:00
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
pub fn queue_slice(&mut self, bytes: &[u8]) {
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
let len = self.buf.len();
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
self.buf.extend_from_slice(bytes);
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
if let Some(cipher) = &mut self.cipher {
cipher.decrypt(&mut self.buf[len..]);
}
2022-04-14 14:55:45 -07:00
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
pub fn queued_bytes(&self) -> &[u8] {
self.buf.as_ref()
2022-04-14 14:55:45 -07:00
}
2022-07-01 15:29:31 -07:00
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
pub fn take_capacity(&mut self) -> BytesMut {
self.buf.split_off(self.buf.len())
}
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
pub fn reserve(&mut self, additional: usize) {
self.buf.reserve(additional);
2022-07-01 15:29:31 -07:00
}
2022-04-14 14:55:45 -07:00
}
#[cfg(test)]
mod tests {
use super::*;
use crate::block_pos::BlockPos;
use crate::entity_meta::PaintingKind;
use crate::ident::Ident;
use crate::item::{ItemKind, ItemStack};
use crate::text::{Text, TextFormat};
use crate::username::Username;
use crate::var_long::VarLong;
use crate::Decode;
#[cfg(feature = "encryption")]
2022-04-14 14:55:45 -07:00
const CRYPT_KEY: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
#[derive(PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 42]
struct TestPacket<'a> {
a: bool,
b: u8,
c: i32,
d: f32,
e: f64,
f: BlockPos,
g: PaintingKind,
h: Ident<&'a str>,
i: Option<ItemStack>,
j: Text,
k: Username<&'a str>,
l: VarInt,
m: VarLong,
n: &'a str,
o: &'a [u8; 10],
p: [u128; 3],
2022-04-14 14:55:45 -07:00
}
impl<'a> TestPacket<'a> {
fn new(n: &'a str) -> Self {
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
Self {
a: true,
b: 12,
c: -999,
d: 5.001,
e: 1e10,
f: BlockPos::new(1, 2, 3),
g: PaintingKind::DonkeyKong,
h: Ident::new("minecraft:whatever").unwrap(),
i: Some(ItemStack::new(ItemKind::WoodenSword, 12, None)),
j: "my ".into_text() + "fancy".italic() + " text",
k: Username::new("00a").unwrap(),
l: VarInt(123),
m: VarLong(456),
n,
o: &[7; 10],
p: [123456789; 3],
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
}
}
fn check(&self, n: &'a str) {
assert_eq!(self, &Self::new(n));
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
}
}
2022-04-14 14:55:45 -07:00
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
#[test]
fn packets_round_trip() {
let mut buf = BytesMut::new();
let mut enc = PacketEncoder::new();
enc.append_packet(&TestPacket::new("first")).unwrap();
#[cfg(feature = "compression")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
enc.set_compression(Some(0));
enc.append_packet(&TestPacket::new("second")).unwrap();
buf.unsplit(enc.take());
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
enc.enable_encryption(&CRYPT_KEY);
enc.append_packet(&TestPacket::new("third")).unwrap();
enc.prepend_packet(&TestPacket::new("fourth")).unwrap();
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
buf.unsplit(enc.take());
let mut dec = PacketDecoder::new();
dec.queue_bytes(buf);
dec.try_next_packet::<TestPacket>()
.unwrap()
.unwrap()
.check("first");
#[cfg(feature = "compression")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
dec.set_compression(true);
dec.try_next_packet::<TestPacket>()
.unwrap()
.unwrap()
.check("second");
#[cfg(feature = "encryption")]
Redesign packet processing and improve `Client` update procedure. (#146) Closes #82 Closes #43 Closes #64 # Changes and Improvements - Packet encoding/decoding happens within `Client` instead of being sent over a channel first. This is better for performance and lays the groundwork for #83. - Reduce the amount of copying necessary by leveraging the `bytes` crate and recent changes to `EncodePacket`. Performance is noticeably improved with maximum players in the `rust-mc-bot` test going from 750 to 1050. - Packet encoding/decoding code is decoupled from IO. This is easier to understand and more suitable for a future protocol lib. - Precise control over the number of bytes that are buffered for sending/receiving. This is important for limiting maximum memory usage correctly. - "packet controllers" are introduced, which are convenient structures for managing packet IO before and during the play state. - `byte_channel` module is created to help implement the `PlayPacketController`. This is essentially a channel of bytes implemented with an `Arc<Mutex<BytesMut>>`. - Error handling in the update procedure for clients was improved using `anyhow::Result<()>` to exit as early as possible. The `client` module is a bit cleaner as a result. - The `LoginPlay` packet is always sent before all other play packets. We no longer have to worry about the behavior of packets sent before that packet. Most packet deferring performed currently can be eliminated. - The packet_inspector was rewritten in response to the above changes. - Timeouts on IO operations behave better. # Known Issues - The packet_inspector now re-encodes packets rather than just decoding them. This will cause problems when trying to use it with the vanilla server because there are missing clientbound packets and other issues. This will be fixed when the protocol module is moved to a separate crate.
2022-11-01 03:11:51 -07:00
dec.enable_encryption(&CRYPT_KEY);
dec.try_next_packet::<TestPacket>()
.unwrap()
.unwrap()
.check("fourth");
dec.try_next_packet::<TestPacket>()
.unwrap()
.unwrap()
.check("third");
2022-04-14 14:55:45 -07:00
}
}