valence/crates/valence_protocol/src/codec.rs

627 lines
17 KiB
Rust
Raw Normal View History

#[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::{Encode, Packet, 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
}
ECS Rewrite (#184) This PR redesigns Valence's architecture around the Bevy Entity Component System framework (`bevy_ecs` and `bevy_app`). Along the way, a large number of changes and improvements have been made. - Valence is now a Bevy plugin. This allows Valence to integrate with the wider Bevy ecosystem. - The `Config` trait has been replaced with the plugin struct which is much easier to configure. Async callbacks are grouped into their own trait. - `World` has been renamed to `Instance` to avoid confusion with `bevy_ecs::world::World`. - Entities, clients, player list, and inventories are all just ECS components/resources. There is no need for us to have our own generational arena/slotmap/etc for each one. - Client events use Bevy's event system. Users can read events with the `EventReader` system parameter. This also means that events are dispatched at an earlier stage of the program where access to the full server is available. There is a special "event loop" stage which is used primarily to avoid the loss of ordering information between events. - Chunks have been completely overhauled to be simpler and faster. The distinction between loaded and unloaded chunks has been mostly eliminated. The per-section bitset that tracked changes has been removed, which should further reduce memory usage. More operations on chunks are available such as removal and cloning. - The full client's game profile is accessible rather than just the textures. - Replaced `vek` with `glam` for parity with Bevy. - Basic inventory support has been added. - Various small changes to `valence_protocol`. - New Examples - The terrain and anvil examples are now fully asynchronous and will not block the main tick loop while chunks are loading. # TODOs - [x] Implement and dispatch client events. - ~~[ ] Finish implementing the new entity/chunk update algorithm.~~ New approach ended up being slower. And also broken. - [x] [Update rust-mc-bot to 1.19.3](https://github.com/Eoghanmc22/rust-mc-bot/pull/3). - [x] Use rust-mc-bot to test for and fix any performance regressions. Revert to old entity/chunk update algorithm if the new one turns out to be slower for some reason. - [x] Make inventories an ECS component. - [x] Make player lists an ECS ~~component~~ resource. - [x] Expose all properties of the client's game profile. - [x] Update the examples. - [x] Update `valence_anvil`. - ~~[ ] Update `valence_spatial_index` to use `glam` instead of `vek`.~~ Maybe later - [x] Make entity events use a bitset. - [x] Update docs. Closes #69 Closes #179 Closes #53 --------- Co-authored-by: Carson McManus <dyc3@users.noreply.github.com> Co-authored-by: AviiNL <me@avii.nl> Co-authored-by: Danik Vitek <x3665107@gmail.com> Co-authored-by: Snowiiii <71594357+Snowiiii@users.noreply.github.com>
2023-02-11 09:51:53 -08:00
#[inline]
pub fn append_bytes(&mut self, bytes: &[u8]) {
self.buf.extend_from_slice(bytes)
}
pub fn prepend_packet<'a, 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: Packet<'a>,
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<'a, P>(&mut self, pkt: &P) -> Result<()>
where
P: Packet<'a>,
{
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<'a, P>(buf: &mut Vec<u8>, pkt: &P) -> Result<()>
where
P: Packet<'a>,
{
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<'a, P>(
buf: &mut Vec<u8>,
pkt: &P,
threshold: u32,
scratch: &mut Vec<u8>,
) -> Result<()>
where
P: Packet<'a>,
{
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: Packet<'a>,
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
}
ECS Rewrite (#184) This PR redesigns Valence's architecture around the Bevy Entity Component System framework (`bevy_ecs` and `bevy_app`). Along the way, a large number of changes and improvements have been made. - Valence is now a Bevy plugin. This allows Valence to integrate with the wider Bevy ecosystem. - The `Config` trait has been replaced with the plugin struct which is much easier to configure. Async callbacks are grouped into their own trait. - `World` has been renamed to `Instance` to avoid confusion with `bevy_ecs::world::World`. - Entities, clients, player list, and inventories are all just ECS components/resources. There is no need for us to have our own generational arena/slotmap/etc for each one. - Client events use Bevy's event system. Users can read events with the `EventReader` system parameter. This also means that events are dispatched at an earlier stage of the program where access to the full server is available. There is a special "event loop" stage which is used primarily to avoid the loss of ordering information between events. - Chunks have been completely overhauled to be simpler and faster. The distinction between loaded and unloaded chunks has been mostly eliminated. The per-section bitset that tracked changes has been removed, which should further reduce memory usage. More operations on chunks are available such as removal and cloning. - The full client's game profile is accessible rather than just the textures. - Replaced `vek` with `glam` for parity with Bevy. - Basic inventory support has been added. - Various small changes to `valence_protocol`. - New Examples - The terrain and anvil examples are now fully asynchronous and will not block the main tick loop while chunks are loading. # TODOs - [x] Implement and dispatch client events. - ~~[ ] Finish implementing the new entity/chunk update algorithm.~~ New approach ended up being slower. And also broken. - [x] [Update rust-mc-bot to 1.19.3](https://github.com/Eoghanmc22/rust-mc-bot/pull/3). - [x] Use rust-mc-bot to test for and fix any performance regressions. Revert to old entity/chunk update algorithm if the new one turns out to be slower for some reason. - [x] Make inventories an ECS component. - [x] Make player lists an ECS ~~component~~ resource. - [x] Expose all properties of the client's game profile. - [x] Update the examples. - [x] Update `valence_anvil`. - ~~[ ] Update `valence_spatial_index` to use `glam` instead of `vek`.~~ Maybe later - [x] Make entity events use a bitset. - [x] Update docs. Closes #69 Closes #179 Closes #53 --------- Co-authored-by: Carson McManus <dyc3@users.noreply.github.com> Co-authored-by: AviiNL <me@avii.nl> Co-authored-by: Danik Vitek <x3665107@gmail.com> Co-authored-by: Snowiiii <71594357+Snowiiii@users.noreply.github.com>
2023-02-11 09:51:53 -08:00
/// Repeatedly decodes a packet type until all packets in the decoder are
/// consumed or an error occurs. The decoded packets are returned in a vec.
///
/// Intended for testing purposes with encryption and compression disabled.
#[track_caller]
pub fn collect_into_vec<'a, P>(&'a mut self) -> Result<Vec<P>>
where
P: Packet<'a>,
ECS Rewrite (#184) This PR redesigns Valence's architecture around the Bevy Entity Component System framework (`bevy_ecs` and `bevy_app`). Along the way, a large number of changes and improvements have been made. - Valence is now a Bevy plugin. This allows Valence to integrate with the wider Bevy ecosystem. - The `Config` trait has been replaced with the plugin struct which is much easier to configure. Async callbacks are grouped into their own trait. - `World` has been renamed to `Instance` to avoid confusion with `bevy_ecs::world::World`. - Entities, clients, player list, and inventories are all just ECS components/resources. There is no need for us to have our own generational arena/slotmap/etc for each one. - Client events use Bevy's event system. Users can read events with the `EventReader` system parameter. This also means that events are dispatched at an earlier stage of the program where access to the full server is available. There is a special "event loop" stage which is used primarily to avoid the loss of ordering information between events. - Chunks have been completely overhauled to be simpler and faster. The distinction between loaded and unloaded chunks has been mostly eliminated. The per-section bitset that tracked changes has been removed, which should further reduce memory usage. More operations on chunks are available such as removal and cloning. - The full client's game profile is accessible rather than just the textures. - Replaced `vek` with `glam` for parity with Bevy. - Basic inventory support has been added. - Various small changes to `valence_protocol`. - New Examples - The terrain and anvil examples are now fully asynchronous and will not block the main tick loop while chunks are loading. # TODOs - [x] Implement and dispatch client events. - ~~[ ] Finish implementing the new entity/chunk update algorithm.~~ New approach ended up being slower. And also broken. - [x] [Update rust-mc-bot to 1.19.3](https://github.com/Eoghanmc22/rust-mc-bot/pull/3). - [x] Use rust-mc-bot to test for and fix any performance regressions. Revert to old entity/chunk update algorithm if the new one turns out to be slower for some reason. - [x] Make inventories an ECS component. - [x] Make player lists an ECS ~~component~~ resource. - [x] Expose all properties of the client's game profile. - [x] Update the examples. - [x] Update `valence_anvil`. - ~~[ ] Update `valence_spatial_index` to use `glam` instead of `vek`.~~ Maybe later - [x] Make entity events use a bitset. - [x] Update docs. Closes #69 Closes #179 Closes #53 --------- Co-authored-by: Carson McManus <dyc3@users.noreply.github.com> Co-authored-by: AviiNL <me@avii.nl> Co-authored-by: Danik Vitek <x3665107@gmail.com> Co-authored-by: Snowiiii <71594357+Snowiiii@users.noreply.github.com>
2023-02-11 09:51:53 -08:00
{
#[cfg(feature = "encryption")]
assert!(
self.cipher.is_none(),
"encryption must be disabled to use this method"
);
#[cfg(feature = "compression")]
assert!(
!self.compression_enabled,
"compression must be disabled to use this method"
);
self.buf.advance(self.cursor);
self.cursor = 0;
let mut res = vec![];
loop {
let mut r = &self.buf[self.cursor..];
let packet_len = match VarInt::decode_partial(&mut r) {
Ok(len) => len,
Err(VarIntDecodeError::Incomplete) => return Ok(res),
Err(VarIntDecodeError::TooLarge) => bail!("malformed packet length VarInt"),
};
ensure!(
(0..=MAX_PACKET_SIZE).contains(&packet_len),
"packet length of {packet_len} is out of bounds"
);
if r.len() < packet_len as usize {
return Ok(res);
}
r = &r[..packet_len as usize];
let packet = P::decode_packet(&mut r)?;
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)");
}
let total_packet_len = VarInt(packet_len).written_size() + packet_len as usize;
self.cursor += total_packet_len;
res.push(packet);
}
}
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 compression(&self) -> bool {
self.compression_enabled
}
#[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::ident::Ident;
use crate::item::{ItemKind, ItemStack};
use crate::text::{Text, TextFormat};
use crate::tracked_data::PaintingKind;
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, Decode, Packet)]
#[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
}
ECS Rewrite (#184) This PR redesigns Valence's architecture around the Bevy Entity Component System framework (`bevy_ecs` and `bevy_app`). Along the way, a large number of changes and improvements have been made. - Valence is now a Bevy plugin. This allows Valence to integrate with the wider Bevy ecosystem. - The `Config` trait has been replaced with the plugin struct which is much easier to configure. Async callbacks are grouped into their own trait. - `World` has been renamed to `Instance` to avoid confusion with `bevy_ecs::world::World`. - Entities, clients, player list, and inventories are all just ECS components/resources. There is no need for us to have our own generational arena/slotmap/etc for each one. - Client events use Bevy's event system. Users can read events with the `EventReader` system parameter. This also means that events are dispatched at an earlier stage of the program where access to the full server is available. There is a special "event loop" stage which is used primarily to avoid the loss of ordering information between events. - Chunks have been completely overhauled to be simpler and faster. The distinction between loaded and unloaded chunks has been mostly eliminated. The per-section bitset that tracked changes has been removed, which should further reduce memory usage. More operations on chunks are available such as removal and cloning. - The full client's game profile is accessible rather than just the textures. - Replaced `vek` with `glam` for parity with Bevy. - Basic inventory support has been added. - Various small changes to `valence_protocol`. - New Examples - The terrain and anvil examples are now fully asynchronous and will not block the main tick loop while chunks are loading. # TODOs - [x] Implement and dispatch client events. - ~~[ ] Finish implementing the new entity/chunk update algorithm.~~ New approach ended up being slower. And also broken. - [x] [Update rust-mc-bot to 1.19.3](https://github.com/Eoghanmc22/rust-mc-bot/pull/3). - [x] Use rust-mc-bot to test for and fix any performance regressions. Revert to old entity/chunk update algorithm if the new one turns out to be slower for some reason. - [x] Make inventories an ECS component. - [x] Make player lists an ECS ~~component~~ resource. - [x] Expose all properties of the client's game profile. - [x] Update the examples. - [x] Update `valence_anvil`. - ~~[ ] Update `valence_spatial_index` to use `glam` instead of `vek`.~~ Maybe later - [x] Make entity events use a bitset. - [x] Update docs. Closes #69 Closes #179 Closes #53 --------- Co-authored-by: Carson McManus <dyc3@users.noreply.github.com> Co-authored-by: AviiNL <me@avii.nl> Co-authored-by: Danik Vitek <x3665107@gmail.com> Co-authored-by: Snowiiii <71594357+Snowiiii@users.noreply.github.com>
2023-02-11 09:51:53 -08:00
#[test]
fn collect_packets_into_vec() {
let packets = vec![
TestPacket::new("foo"),
TestPacket::new("bar"),
TestPacket::new("baz"),
];
let mut enc = PacketEncoder::new();
let mut dec = PacketDecoder::new();
for pkt in &packets {
enc.append_packet(pkt).unwrap();
}
dec.queue_bytes(enc.take());
let res = dec.collect_into_vec::<TestPacket>().unwrap();
assert_eq!(packets, res);
}
2022-04-14 14:55:45 -07:00
}