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

649 lines
21 KiB
Rust
Raw Normal View History

2022-07-14 23:18:20 -07:00
//! The heart of the server.
2022-04-14 14:55:45 -07:00
use std::error::Error;
use std::iter::FusedIterator;
use std::net::{IpAddr, SocketAddr};
use std::sync::atomic::{AtomicI64, Ordering};
2022-06-30 13:22:08 -07:00
use std::sync::{Arc, Mutex};
2022-04-14 14:55:45 -07:00
use std::time::{Duration, Instant};
use std::{io, thread};
2022-04-14 14:55:45 -07:00
use anyhow::{ensure, Context};
2022-04-14 14:55:45 -07:00
use flume::{Receiver, Sender};
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(crate) use packet_controller::PlayPacketController;
2022-04-14 14:55:45 -07:00
use rand::rngs::OsRng;
use rayon::iter::ParallelIterator;
use reqwest::Client as HttpClient;
use rsa::{PublicKeyParts, RsaPrivateKey};
2022-04-14 14:55:45 -07:00
use serde_json::{json, Value};
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
use tokio::net::{TcpListener, TcpStream};
use tokio::runtime::{Handle, Runtime};
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 tokio::sync::Semaphore;
2022-04-14 14:55:45 -07:00
use uuid::Uuid;
use valence_nbt::{compound, Compound, List};
use valence_protocol::codec::{PacketDecoder, PacketEncoder};
use valence_protocol::packets::c2s::handshake::HandshakeOwned;
use valence_protocol::packets::c2s::login::LoginStart;
use valence_protocol::packets::c2s::status::{PingRequest, StatusRequest};
use valence_protocol::packets::s2c::login::{DisconnectLogin, LoginSuccess, SetCompression};
use valence_protocol::packets::s2c::status::{PingResponse, StatusResponse};
use valence_protocol::types::HandshakeNextState;
use valence_protocol::username::Username;
use valence_protocol::var_int::VarInt;
use valence_protocol::{ident, MINECRAFT_VERSION, PROTOCOL_VERSION};
2022-04-14 14:55:45 -07:00
use crate::biome::{validate_biomes, Biome, BiomeId};
use crate::client::{Client, Clients};
use crate::config::{Config, ConnectionMode, ServerListPing};
use crate::dimension::{validate_dimensions, Dimension, DimensionId};
use crate::entity::Entities;
use crate::inventory::Inventories;
2022-08-09 14:44:04 -07:00
use crate::player_list::PlayerLists;
use crate::player_textures::SignedPlayerTextures;
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 crate::server::packet_controller::InitialPacketController;
use crate::world::Worlds;
use crate::Ticks;
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
mod byte_channel;
mod login;
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
mod packet_controller;
2022-07-11 05:08:02 -07:00
/// Contains the entire state of a running Minecraft server, accessible from
/// within the [update](crate::config::Config::update) loop.
2022-07-15 20:40:39 -07:00
pub struct Server<C: Config> {
2022-07-27 19:21:11 -07:00
/// Custom state.
pub state: C::ServerState,
2022-07-11 05:08:02 -07:00
/// A handle to this server's [`SharedServer`].
2022-07-15 20:40:39 -07:00
pub shared: SharedServer<C>,
2022-09-02 00:06:45 -07:00
/// All of the clients on the server.
2022-07-15 20:40:39 -07:00
pub clients: Clients<C>,
2022-09-02 00:06:45 -07:00
/// All of entities on the server.
2022-07-15 20:40:39 -07:00
pub entities: Entities<C>,
2022-09-02 00:06:45 -07:00
/// All of the worlds on the server.
2022-07-15 20:40:39 -07:00
pub worlds: Worlds<C>,
2022-09-02 00:06:45 -07:00
/// All of the player lists on the server.
2022-08-09 14:44:04 -07:00
pub player_lists: PlayerLists<C>,
pub inventories: Inventories,
}
2022-07-11 05:08:02 -07:00
/// A handle to a Minecraft server containing the subset of functionality which
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
/// is accessible outside the [update] loop.
2022-07-11 05:08:02 -07:00
///
/// `SharedServer`s are internally refcounted and can
/// be shared between threads.
///
/// [update]: crate::config::Config::update
2022-07-15 20:40:39 -07:00
pub struct SharedServer<C: Config>(Arc<SharedServerInner<C>>);
impl<C: Config> Clone for SharedServer<C> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
struct SharedServerInner<C: Config> {
cfg: C,
2022-04-14 14:55:45 -07:00
address: SocketAddr,
tick_rate: Ticks,
connection_mode: ConnectionMode,
max_connections: usize,
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
incoming_capacity: usize,
outgoing_capacity: usize,
/// The tokio handle used by the server.
2022-04-14 14:55:45 -07:00
tokio_handle: Handle,
/// Holding a runtime handle is not enough to keep tokio working. We need
/// to store the runtime here so we don't drop it.
_tokio_runtime: Option<Runtime>,
2022-04-14 14:55:45 -07:00
dimensions: Vec<Dimension>,
biomes: Vec<Biome>,
/// Contains info about dimensions, biomes, and chats.
/// Sent to all clients when joining.
registry_codec: Compound,
2022-04-14 14:55:45 -07:00
/// The instant the server was started.
start_instant: Instant,
/// Receiver for new clients past the login stage.
new_clients_rx: Receiver<NewClientMessage>,
new_clients_tx: Sender<NewClientMessage>,
/// Incremented on every game tick.
tick_counter: AtomicI64,
2022-04-14 14:55:45 -07:00
/// A semaphore used to limit the number of simultaneous connections to the
/// server. Closing this semaphore stops new connections.
connection_sema: Arc<Semaphore>,
/// The result that will be returned when the server is shut down.
shutdown_result: Mutex<Option<ShutdownResult>>,
/// The RSA keypair used for encryption with clients.
rsa_key: RsaPrivateKey,
/// The public part of `rsa_key` encoded in DER, which is an ASN.1 format.
/// This is sent to clients during the authentication process.
public_key_der: Box<[u8]>,
/// For session server requests.
http_client: HttpClient,
}
/// Contains information about a new client.
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
#[non_exhaustive]
2022-04-14 14:55:45 -07:00
pub struct NewClientData {
2022-07-14 23:18:20 -07:00
/// The UUID of the new client.
2022-04-14 14:55:45 -07:00
pub uuid: Uuid,
2022-07-14 23:18:20 -07:00
/// The username of the new client.
pub username: Username<String>,
2022-07-14 23:18:20 -07:00
/// The new client's player textures. May be `None` if the client does not
/// have a skin or cape.
pub textures: Option<SignedPlayerTextures>,
2022-07-14 23:18:20 -07:00
/// The remote address of the new client.
pub remote_addr: IpAddr,
2022-04-14 14:55:45 -07:00
}
struct NewClientMessage {
ncd: NewClientData,
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
ctrl: PlayPacketController,
2022-04-14 14:55:45 -07:00
}
2022-07-11 05:08:02 -07:00
/// The result type returned from [`start_server`].
pub type ShutdownResult = Result<(), Box<dyn Error + Send + Sync + 'static>>;
2022-04-14 14:55:45 -07:00
2022-07-15 20:40:39 -07:00
impl<C: Config> SharedServer<C> {
2022-07-11 05:08:02 -07:00
/// Gets a reference to the config object used to start the server.
2022-07-15 20:40:39 -07:00
pub fn config(&self) -> &C {
&self.0.cfg
2022-04-14 14:55:45 -07:00
}
2022-07-11 05:08:02 -07:00
/// Gets the socket address this server is bound to.
2022-04-14 14:55:45 -07:00
pub fn address(&self) -> SocketAddr {
self.0.address
}
2022-07-11 05:08:02 -07:00
/// Gets the configured tick rate of this server.
pub fn tick_rate(&self) -> Ticks {
self.0.tick_rate
2022-04-14 14:55:45 -07:00
}
/// Gets the connection mode of the server.
pub fn connection_mode(&self) -> &ConnectionMode {
&self.0.connection_mode
2022-04-14 14:55:45 -07:00
}
2022-07-11 05:08:02 -07:00
/// Gets the maximum number of connections allowed to the server at once.
pub fn max_connections(&self) -> usize {
self.0.max_connections
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
/// Gets the configured incoming capacity.
pub fn incoming_capacity(&self) -> usize {
self.0.incoming_capacity
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
/// Gets the configured outgoing incoming capacity.
pub fn outgoing_capacity(&self) -> usize {
self.0.outgoing_capacity
2022-04-14 14:55:45 -07:00
}
2022-07-11 05:08:02 -07:00
/// Gets a handle to the tokio instance this server is using.
2022-04-14 14:55:45 -07:00
pub fn tokio_handle(&self) -> &Handle {
&self.0.tokio_handle
}
/// Obtains a [`Dimension`] by using its corresponding [`DimensionId`].
///
/// It is safe but unspecified behavior to call this function using a
/// [`DimensionId`] not originating from the configuration used to construct
/// the server.
pub fn dimension(&self, id: DimensionId) -> &Dimension {
self.0
.dimensions
.get(id.0 as usize)
.expect("invalid dimension ID")
}
/// Returns an iterator over all added dimensions and their associated
/// [`DimensionId`].
pub fn dimensions(&self) -> impl FusedIterator<Item = (DimensionId, &Dimension)> + Clone {
2022-04-14 14:55:45 -07:00
self.0
.dimensions
.iter()
.enumerate()
.map(|(i, d)| (DimensionId(i as u16), d))
2022-04-14 14:55:45 -07:00
}
/// Obtains a [`Biome`] by using its corresponding [`BiomeId`].
2022-09-02 00:06:45 -07:00
///
/// It is safe but unspecified behavior to call this function using a
/// [`BiomeId`] not originating from the configuration used to construct
/// the server.
2022-04-14 14:55:45 -07:00
pub fn biome(&self, id: BiomeId) -> &Biome {
self.0.biomes.get(id.0 as usize).expect("invalid biome ID")
}
/// Returns an iterator over all added biomes and their associated
/// [`BiomeId`] in ascending order.
pub fn biomes(
&self,
) -> impl ExactSizeIterator<Item = (BiomeId, &Biome)> + DoubleEndedIterator + FusedIterator + Clone
{
2022-04-14 14:55:45 -07:00
self.0
.biomes
.iter()
.enumerate()
.map(|(i, b)| (BiomeId(i as u16), b))
2022-04-14 14:55:45 -07:00
}
pub(crate) fn registry_codec(&self) -> &Compound {
&self.0.registry_codec
}
2022-04-14 14:55:45 -07:00
/// Returns the instant the server was started.
pub fn start_instant(&self) -> Instant {
self.0.start_instant
}
/// Returns the number of ticks that have elapsed since the server began.
pub fn current_tick(&self) -> Ticks {
self.0.tick_counter.load(Ordering::SeqCst)
}
2022-04-14 14:55:45 -07:00
/// Immediately stops new connections to the server and initiates server
2022-07-11 05:08:02 -07:00
/// shutdown. The given result is returned through [`start_server`].
2022-04-14 14:55:45 -07:00
///
/// You may want to disconnect all players with a message prior to calling
/// this function.
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 shutdown<E>(&self, res: Result<(), E>)
2022-04-14 14:55:45 -07:00
where
E: Into<Box<dyn Error + Send + Sync + 'static>>,
{
self.0.connection_sema.close();
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.0.shutdown_result.lock().unwrap() = Some(res.map_err(|e| e.into()));
2022-04-14 14:55:45 -07:00
}
}
/// Consumes the configuration and starts the server.
///
/// This function blocks the current thread and returns once the server has shut
/// down, a runtime error occurs, or the configuration is found to be invalid.
2022-07-27 19:21:11 -07:00
pub fn start_server<C: Config>(config: C, data: C::ServerState) -> ShutdownResult {
let shared = setup_server(config)
.context("failed to initialize server")
.map_err(Box::<dyn Error + Send + Sync + 'static>::from)?;
let _guard = shared.tokio_handle().enter();
let mut server = Server {
2022-07-27 19:21:11 -07:00
state: data,
shared: shared.clone(),
clients: Clients::new(),
entities: Entities::new(),
worlds: Worlds::new(shared.clone()),
2022-08-09 14:44:04 -07:00
player_lists: PlayerLists::new(),
inventories: Inventories::new(),
};
shared.config().init(&mut server);
tokio::spawn(do_accept_loop(shared));
do_update_loop(&mut server)
}
2022-07-15 20:40:39 -07:00
fn setup_server<C: Config>(cfg: C) -> anyhow::Result<SharedServer<C>> {
let max_connections = cfg.max_connections();
let address = cfg.address();
let tick_rate = cfg.tick_rate();
ensure!(tick_rate > 0, "tick rate must be greater than zero");
let connection_mode = cfg.connection_mode();
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 incoming_packet_capacity = cfg.incoming_capacity();
ensure!(
incoming_packet_capacity > 0,
"serverbound packet capacity must be nonzero"
);
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 outgoing_packet_capacity = cfg.outgoing_capacity();
ensure!(
outgoing_packet_capacity > 0,
"outgoing packet capacity must be nonzero"
);
let tokio_handle = cfg.tokio_handle();
let dimensions = cfg.dimensions();
validate_dimensions(&dimensions)?;
let biomes = cfg.biomes();
validate_biomes(&biomes)?;
2022-04-14 14:55:45 -07:00
let rsa_key = RsaPrivateKey::new(&mut OsRng, 1024)?;
let public_key_der =
rsa_der::public_key_to_der(&rsa_key.n().to_bytes_be(), &rsa_key.e().to_bytes_be())
.into_boxed_slice();
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 (new_clients_tx, new_clients_rx) = flume::bounded(1024);
2022-04-14 14:55:45 -07:00
let runtime = if tokio_handle.is_none() {
2022-04-14 14:55:45 -07:00
Some(Runtime::new()?)
} else {
None
};
let tokio_handle = match &runtime {
2022-04-14 14:55:45 -07:00
Some(rt) => rt.handle().clone(),
None => tokio_handle.unwrap(),
2022-04-14 14:55:45 -07:00
};
let registry_codec = make_registry_codec(&dimensions, &biomes);
let server = SharedServerInner {
2022-07-15 20:40:39 -07:00
cfg,
address,
tick_rate,
connection_mode,
max_connections,
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
incoming_capacity: incoming_packet_capacity,
outgoing_capacity: outgoing_packet_capacity,
tokio_handle,
_tokio_runtime: runtime,
dimensions,
biomes,
registry_codec,
2022-04-14 14:55:45 -07:00
start_instant: Instant::now(),
new_clients_rx,
new_clients_tx,
tick_counter: AtomicI64::new(0),
connection_sema: Arc::new(Semaphore::new(max_connections)),
2022-04-14 14:55:45 -07:00
shutdown_result: Mutex::new(None),
rsa_key,
public_key_der,
http_client: HttpClient::new(),
};
Ok(SharedServer(Arc::new(server)))
2022-04-14 14:55:45 -07:00
}
fn make_registry_codec(dimensions: &[Dimension], biomes: &[Biome]) -> Compound {
compound! {
ident!("dimension_type") => compound! {
"type" => ident!("dimension_type"),
"value" => List::Compound(dimensions.iter().enumerate().map(|(id, dim)| compound! {
"name" => DimensionId(id as u16).dimension_type_name(),
"id" => id as i32,
"element" => dim.to_dimension_registry_item(),
}).collect()),
},
ident!("worldgen/biome") => compound! {
"type" => ident!("worldgen/biome"),
"value" => {
2022-10-13 18:19:35 -07:00
List::Compound(biomes
.iter()
.enumerate()
.map(|(id, biome)| biome.to_biome_registry_item(id as i32))
2022-10-13 18:19:35 -07:00
.collect())
}
2022-10-13 18:19:35 -07:00
},
2022-11-12 14:32:00 +00:00
ident!("chat_type") => compound! {
"type" => ident!("chat_type"),
"value" => List::Compound(Vec::new()),
},
}
}
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 do_update_loop(server: &mut Server<impl Config>) -> ShutdownResult {
let mut tick_start = Instant::now();
2022-04-14 14:55:45 -07:00
let shared = server.shared.clone();
2022-04-14 14:55:45 -07:00
loop {
if let Some(res) = shared.0.shutdown_result.lock().unwrap().take() {
2022-04-14 14:55:45 -07:00
return res;
}
while let Ok(msg) = shared.0.new_clients_rx.try_recv() {
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
server
.clients
.insert(Client::new(msg.ctrl, msg.ncd, Default::default()));
2022-04-14 14:55:45 -07:00
}
2022-06-24 16:11:15 -07:00
// Get serverbound packets first so they are not dealt with a tick late.
server.clients.par_iter_mut().for_each(|(_, client)| {
client.handle_serverbound_packets(&server.entities);
2022-06-24 16:11:15 -07:00
});
shared.config().update(server);
2022-04-14 14:55:45 -07:00
server.worlds.par_iter_mut().for_each(|(id, world)| {
world.spatial_index.update(&server.entities, id);
});
2022-06-19 00:25:25 -07:00
server.clients.par_iter_mut().for_each(|(_, client)| {
2022-08-09 14:44:04 -07:00
client.update(
&shared,
&server.entities,
&server.worlds,
&server.player_lists,
&server.inventories,
2022-08-09 14:44:04 -07:00
);
});
2022-04-14 14:55:45 -07:00
server.entities.update();
2022-04-14 14:55:45 -07:00
server.worlds.par_iter_mut().for_each(|(_, world)| {
2022-08-10 20:09:10 -07:00
world.chunks.update();
2022-04-29 00:48:41 -07:00
});
2022-04-14 14:55:45 -07:00
2022-08-09 14:44:04 -07:00
server.player_lists.update();
server.inventories.update();
2022-08-09 14:44:04 -07:00
2022-04-29 00:48:41 -07:00
// Sleep for the remainder of the tick.
let tick_duration = Duration::from_secs_f64((shared.0.tick_rate as f64).recip());
thread::sleep(tick_duration.saturating_sub(tick_start.elapsed()));
2022-04-14 14:55:45 -07:00
tick_start = Instant::now();
shared.0.tick_counter.fetch_add(1, Ordering::SeqCst);
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
async fn do_accept_loop(server: SharedServer<impl Config>) {
2022-04-14 14:55:45 -07:00
log::trace!("entering accept loop");
let listener = match TcpListener::bind(server.0.address).await {
Ok(listener) => listener,
Err(e) => {
server.shutdown(Err(e).context("failed to start TCP listener"));
return;
}
};
loop {
match server.0.connection_sema.clone().acquire_owned().await {
Ok(permit) => match listener.accept().await {
Ok((stream, remote_addr)) => {
let server = server.clone();
tokio::spawn(async move {
if let Err(e) = stream.set_nodelay(true) {
2022-07-06 02:11:15 -07:00
log::error!("failed to set TCP_NODELAY: {e}");
2022-04-14 14:55:45 -07:00
}
if let Err(e) = handle_connection(server, stream, remote_addr).await {
2022-07-06 02:11:15 -07:00
if let Some(e) = e.downcast_ref::<io::Error>() {
if e.kind() == io::ErrorKind::UnexpectedEof {
return;
}
}
2022-07-11 05:08:02 -07:00
log::error!("connection to {remote_addr} ended: {e:#}");
2022-04-14 14:55:45 -07:00
}
drop(permit);
});
}
Err(e) => {
log::error!("failed to accept incoming connection: {e}");
}
},
// Closed semaphore indicates server shutdown.
Err(_) => return,
}
}
}
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
async fn handle_connection(
server: SharedServer<impl Config>,
2022-04-14 14:55:45 -07:00
stream: TcpStream,
remote_addr: SocketAddr,
) -> anyhow::Result<()> {
let (read, write) = stream.into_split();
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 ctrl = InitialPacketController::new(
read,
write,
PacketEncoder::new(),
PacketDecoder::new(),
Duration::from_secs(5),
);
2022-04-14 14:55:45 -07:00
// TODO: peek stream for 0xFE legacy ping
let handshake = ctrl.recv_packet::<HandshakeOwned>().await?;
ensure!(
matches!(server.connection_mode(), ConnectionMode::BungeeCord)
|| handshake.server_address.chars().count() <= 255,
"handshake server address is too long"
);
2022-08-14 15:18:22 -07:00
match handshake.next_state {
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
HandshakeNextState::Status => handle_status(server, ctrl, remote_addr, handshake)
2022-04-14 14:55:45 -07:00
.await
.context("error during status"),
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
HandshakeNextState::Login => match handle_login(&server, &mut ctrl, remote_addr, handshake)
2022-04-14 14:55:45 -07:00
.await
.context("error during login")?
{
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
Some(ncd) => {
let msg = NewClientMessage {
ncd,
ctrl: ctrl.into_play_packet_controller(
server.0.incoming_capacity,
server.0.outgoing_capacity,
server.tokio_handle().clone(),
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 _ = server.0.new_clients_tx.send_async(msg).await;
Ok(())
}
2022-04-14 14:55:45 -07:00
None => 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
async fn handle_status(
server: SharedServer<impl Config>,
mut ctrl: InitialPacketController<OwnedReadHalf, OwnedWriteHalf>,
2022-04-14 14:55:45 -07:00
remote_addr: SocketAddr,
handshake: HandshakeOwned,
2022-04-14 14:55:45 -07:00
) -> anyhow::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
ctrl.recv_packet::<StatusRequest>().await?;
2022-04-14 14:55:45 -07:00
2022-08-14 15:18:22 -07:00
match server
.0
.cfg
.server_list_ping(&server, remote_addr, handshake.protocol_version.0)
.await
{
2022-04-14 14:55:45 -07:00
ServerListPing::Respond {
online_players,
max_players,
player_sample,
2022-04-14 14:55:45 -07:00
description,
favicon_png,
} => {
let mut json = json!({
"version": {
"name": MINECRAFT_VERSION,
2022-04-14 14:55:45 -07:00
"protocol": PROTOCOL_VERSION
},
"players": {
"online": online_players,
"max": max_players,
"sample": player_sample,
2022-04-14 14:55:45 -07:00
},
"description": description,
});
if let Some(data) = favicon_png {
let mut buf = "data:image/png;base64,".to_owned();
2022-04-14 14:55:45 -07:00
base64::encode_config_buf(data, base64::STANDARD, &mut buf);
json.as_object_mut()
.unwrap()
.insert("favicon".to_owned(), Value::String(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
ctrl.send_packet(&StatusResponse {
json: &json.to_string(),
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
})
.await?;
2022-04-14 14:55:45 -07:00
}
ServerListPing::Ignore => return 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
let PingRequest { payload } = ctrl.recv_packet().await?;
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
ctrl.send_packet(&PingResponse { payload }).await?;
2022-04-14 14:55:45 -07:00
Ok(())
}
/// Handle the login process and return the new client's data if successful.
async fn handle_login(
server: &SharedServer<impl Config>,
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
ctrl: &mut InitialPacketController<OwnedReadHalf, OwnedWriteHalf>,
2022-04-14 14:55:45 -07:00
remote_addr: SocketAddr,
handshake: HandshakeOwned,
2022-04-14 14:55:45 -07:00
) -> anyhow::Result<Option<NewClientData>> {
2022-08-14 15:18:22 -07:00
if handshake.protocol_version.0 != PROTOCOL_VERSION {
// TODO: send translated disconnect msg?
return Ok(None);
}
2022-04-14 14:55:45 -07:00
let LoginStart {
username,
2022-08-30 18:41:17 -07:00
sig_data: _, // TODO
profile_id: _, // TODO
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
} = ctrl.recv_packet().await?;
2022-04-14 14:55:45 -07:00
let username = username.to_owned_username();
let ncd = match server.connection_mode() {
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
ConnectionMode::Online => login::online(server, ctrl, remote_addr, username).await?,
ConnectionMode::Offline => login::offline(remote_addr, username)?,
ConnectionMode::BungeeCord => login::bungeecord(&handshake.server_address, username)?,
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
ConnectionMode::Velocity { secret } => login::velocity(ctrl, username, secret).await?,
2022-04-14 14:55:45 -07:00
};
if let Some(threshold) = server.0.cfg.compression_threshold() {
ctrl.send_packet(&SetCompression {
threshold: VarInt(threshold as i32),
})
.await?;
2022-04-14 14:55:45 -07:00
ctrl.set_compression(Some(threshold));
}
2022-04-14 14:55:45 -07:00
2022-08-05 12:36:34 -07:00
if let Err(reason) = server.0.cfg.login(server, &ncd).await {
2022-04-14 14:55:45 -07:00
log::info!("Disconnect at login: \"{reason}\"");
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
ctrl.send_packet(&DisconnectLogin { reason }).await?;
2022-04-14 14:55:45 -07:00
return Ok(None);
}
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
ctrl.send_packet(&LoginSuccess {
uuid: ncd.uuid,
username: ncd.username.as_str_username(),
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
properties: Vec::new(),
})
.await?;
2022-04-14 14:55:45 -07:00
2022-08-05 12:36:34 -07:00
Ok(Some(ncd))
2022-04-14 14:55:45 -07:00
}