Clean up Config docs and add compression threshold (#148)

This commit is contained in:
Ryan Johnson 2022-11-01 20:27:08 -07:00 committed by GitHub
parent a885b949da
commit ff136c2a4a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 49 deletions

View file

@ -85,9 +85,9 @@ pub trait Config: Sized + Send + Sync + 'static {
STANDARD_TPS
}
/// Called once at startup to get the connection mode option, which
/// determines if client authentication and encryption should take place
/// and if the server should get the player data from a proxy.
/// Called to get the connection mode option, which determines if client
/// authentication and encryption should take place and if the server
/// should get the player data from a proxy.
///
/// # Default Implementation
///
@ -96,13 +96,62 @@ pub trait Config: Sized + Send + Sync + 'static {
ConnectionMode::Online
}
/// Called once at startup to get the "prevent-proxy-connections" option,
/// which determines if client IP validation should take place.
///
/// When prevent_proxy_connections is enabled, clients can no longer log-in
/// if they connected to the yggdrasil server using a different IP.
/// Obtains the compression threshold to use for compressing packets. For a
/// compression threshold of `Some(N)`, packets with encoded lengths >= `N`
/// are compressed while all others are not. `None` disables compression.
///
/// # Default Implementation
///
/// If the connection mode is [`ConnectionMode::Online`], `Some(256)` is
/// returned. Otherwise, compression is disabled.
fn compression_threshold(&self) -> Option<u32> {
match self.connection_mode() {
ConnectionMode::Online => Some(256),
_ => None,
}
}
/// Called upon every client login to obtain the full URL to use for session
/// server requests. This is done to authenticate player accounts. This
/// method is not called unless [online mode] is enabled.
///
/// It is assumed that upon successful request, a structure matching the
/// description in the [wiki](https://wiki.vg/Protocol_Encryption#Server) was obtained.
/// Providing a URL that does not return such a structure will result in a
/// disconnect for every client that connects.
///
/// The arguments are described in the linked wiki article.
///
/// # Default Implementation
///
/// Uses the official Minecraft session server. This is formatted as
/// `https://sessionserver.mojang.com/session/minecraft/hasJoined?username=<username>&serverId=<auth-digest>&ip=<player-ip>`.
///
/// [online mode]: crate::config::ConnectionMode::Online
fn session_server(
&self,
server: &SharedServer<Self>,
username: Username<&str>,
auth_digest: &str,
player_ip: &IpAddr,
) -> String {
if self.prevent_proxy_connections() {
format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={auth_digest}&ip={player_ip}")
} else {
format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={auth_digest}")
}
}
/// Called from the default implementation of [`Config::session_server`] to
/// get the "prevent-proxy-connections" option, which determines if client
/// IP validation should take place.
///
/// When `prevent_proxy_connections` is enabled, clients can no longer
/// log-in if they connected to the yggdrasil server using a different
/// IP.
///
/// # Default Implementation
///
/// Proxy connections are allowed.
///
/// Returns `false`.
@ -119,8 +168,8 @@ pub trait Config: Sized + Send + Sync + 'static {
///
/// # Default Implementation
///
/// An unspecified value is returned that should be adequate in most
/// situations.
/// An unspecified value is returned that should be adequate for most
/// situations. This default may change in future versions.
fn incoming_capacity(&self) -> usize {
MAX_PACKET_SIZE as usize
}
@ -134,8 +183,8 @@ pub trait Config: Sized + Send + Sync + 'static {
///
/// # Default Implementation
///
/// An unspecified value is returned that should be adequate in most
/// situations.
/// An unspecified value is returned that should be adequate for most
/// situations. This default may change in future versions.
fn outgoing_capacity(&self) -> usize {
MAX_PACKET_SIZE as usize * 4
}
@ -229,30 +278,6 @@ pub trait Config: Sized + Send + Sync + 'static {
Ok(())
}
/// Called upon (every) client connect (if online mode is enabled) to obtain
/// the full URL to use for session server requests. Defaults to
/// `https://sessionserver.mojang.com/session/minecraft/hasJoined?username=<username>&serverId=<auth-digest>&ip=<player-ip>`.
///
/// It is assumed, that upon successful request, a structure matching the
/// description in the [wiki](https://wiki.vg/Protocol_Encryption#Server) was obtained.
/// Providing a URL that does not return such a structure will result in a
/// disconnect for every client that connects.
///
/// The arguments are described in the linked wiki article.
fn format_session_server_url(
&self,
server: &SharedServer<Self>,
username: Username<&str>,
auth_digest: &str,
player_ip: &IpAddr,
) -> String {
if self.prevent_proxy_connections() {
format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={auth_digest}&ip={player_ip}")
} else {
format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={auth_digest}")
}
}
/// Called after the server is created, but prior to accepting connections
/// and entering the update loop.
///
@ -276,7 +301,7 @@ pub trait Config: Sized + Send + Sync + 'static {
/// # Default Implementation
///
/// The default implementation does nothing.
fn update(&self, server: &mut Server<Self>);
fn update(&self, server: &mut Server<Self>) {}
}
/// The result of the [`server_list_ping`](Config::server_list_ping) callback.
@ -316,7 +341,7 @@ pub enum ConnectionMode {
/// This mode should be used for all publicly exposed servers which are not
/// behind a proxy.
///
/// [configured session server]: Config::format_session_server_url
/// [configured session server]: Config::session_server
#[default]
Online,
/// Disables client authentication with the configured session server.
@ -395,6 +420,4 @@ where
type WorldState = W;
type ChunkState = Ch;
type PlayerListState = P;
fn update(&self, _server: &mut Server<Self>) {}
}

View file

@ -53,7 +53,7 @@ impl PacketEncoder {
if let Some(threshold) = self.compression_threshold {
if data_len >= threshold as usize {
let mut z = ZlibEncoder::new(&mut self.compress_buf, Compression::best());
let mut z = ZlibEncoder::new(&mut self.compress_buf, Compression::new(4));
pkt.encode_packet(&mut z)?;
drop(z);

View file

@ -615,13 +615,14 @@ async fn handle_login(
ConnectionMode::Velocity { secret } => login::velocity(ctrl, username, secret).await?,
};
let compression_threshold = 256;
if let Some(threshold) = server.0.cfg.compression_threshold() {
ctrl.send_packet(&SetCompression {
threshold: VarInt(compression_threshold as i32),
threshold: VarInt(threshold as i32),
})
.await?;
ctrl.set_compression(Some(compression_threshold));
ctrl.set_compression(Some(threshold));
}
if let Err(reason) = server.0.cfg.login(server, &ncd).await {
log::info!("Disconnect at login: \"{reason}\"");

View file

@ -123,7 +123,7 @@ impl ByteSender {
pub enum TrySendError {
#[error("sender disconnected")]
Disconnected(BytesMut),
#[error("channel full")]
#[error("channel full (see `Config::outgoing_capacity`)")]
Full(BytesMut),
}

View file

@ -96,7 +96,7 @@ pub(super) async fn online(
.chain(&server.0.public_key_der)
.finalize();
let url = server.config().format_session_server_url(
let url = server.config().session_server(
server,
username.as_str_username(),
&auth_digest(&hash),