valence/src/config.rs

271 lines
9.5 KiB
Rust
Raw Normal View History

2022-07-15 16:18:20 +10:00
//! Configuration for the server.
use std::borrow::Cow;
2022-04-15 07:55:45 +10:00
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::panic::{RefUnwindSafe, UnwindSafe};
2022-04-15 07:55:45 +10:00
use async_trait::async_trait;
use serde::Serialize;
2022-04-15 07:55:45 +10:00
use tokio::runtime::Handle as TokioHandle;
use uuid::Uuid;
2022-04-15 07:55:45 +10:00
use crate::biome::Biome;
use crate::dimension::Dimension;
use crate::server::{NewClientData, Server, SharedServer};
use crate::text::Text;
2022-07-18 14:29:44 +10:00
use crate::{Ticks, STANDARD_TPS};
2022-04-15 07:55:45 +10:00
2022-07-16 13:40:39 +10:00
/// A trait for the configuration of a server.
///
2022-07-11 22:08:02 +10:00
/// This trait uses the [async_trait] attribute macro. It is exported at the
2022-09-02 17:06:45 +10:00
/// root of this crate. async_trait will be removed once async fns in traits
/// are stabilized.
2022-07-11 22:08:02 +10:00
///
/// [async_trait]: https://docs.rs/async-trait/latest/async_trait/
#[async_trait]
#[allow(unused_variables)]
2022-09-02 17:06:45 +10:00
pub trait Config: Sized + Send + Sync + UnwindSafe + RefUnwindSafe + 'static {
2022-07-28 12:21:11 +10:00
/// Custom state to store with the [`Server`].
type ServerState: Send + Sync;
/// Custom state to store with every [`Client`](crate::client::Client).
type ClientState: Default + Send + Sync;
/// Custom state to store with every [`Entity`](crate::entity::Entity).
type EntityState: Send + Sync;
/// Custom state to store with every [`World`](crate::world::World).
type WorldState: Send + Sync;
/// Custom state to store with every
/// [`LoadedChunk`](crate::chunk::LoadedChunk).
2022-07-28 12:21:11 +10:00
type ChunkState: Send + Sync;
/// Custom state to store with every
/// [`PlayerList`](crate::player_list::PlayerList).
2022-08-10 07:44:04 +10:00
type PlayerListState: Send + Sync;
2022-07-16 13:40:39 +10:00
/// Called once at startup to get the maximum number of simultaneous
/// connections allowed to the server. This includes all
/// connections, not just those past the login stage.
///
/// You will want this value to be somewhere above the maximum number of
/// players, since status pings should still succeed even when the server is
/// full.
fn max_connections(&self) -> usize;
2022-04-15 07:55:45 +10:00
/// Called once at startup to get the socket address the server will
/// be bound to.
2022-04-15 07:55:45 +10:00
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// Returns `127.0.0.1:25565`.
fn address(&self) -> SocketAddr {
SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 25565).into()
2022-04-15 07:55:45 +10:00
}
/// Called once at startup to get the tick rate, which is the number of game
/// updates that should occur in one second.
2022-04-15 07:55:45 +10:00
///
/// On each game update (tick), the server is expected to update game logic
/// and respond to packets from clients. Once this is complete, the server
/// will sleep for any remaining time until a full tick has passed.
2022-04-15 07:55:45 +10:00
///
/// The tick rate must be greater than zero.
2022-04-15 07:55:45 +10:00
///
/// Note that the official Minecraft client only processes packets at 20hz,
/// so there is little benefit to a tick rate higher than 20.
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
2022-07-18 14:29:44 +10:00
/// Returns [`STANDARD_TPS`].
fn tick_rate(&self) -> Ticks {
2022-07-18 14:29:44 +10:00
STANDARD_TPS
2022-04-15 07:55:45 +10:00
}
/// Called once at startup to get the "online mode" option, which determines
/// if client authentication and encryption should take place.
2022-04-15 07:55:45 +10:00
///
/// When online mode is disabled, malicious clients can give themselves any
/// username and UUID they want, potentially gaining privileges they
/// might not otherwise have. Additionally, encryption is only enabled in
/// online mode. For these reasons online mode should only be disabled
/// for development purposes and enabled on servers exposed to the
/// internet.
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// Returns `true`.
fn online_mode(&self) -> bool {
true
2022-04-15 07:55:45 +10:00
}
/// Called once at startup to get the capacity of the buffer used to
/// hold incoming packets.
2022-04-15 07:55:45 +10:00
///
2022-09-02 17:06:45 +10:00
/// A larger capacity reduces the chance that a client needs to be
/// disconnected due to a full buffer, but increases potential memory usage.
2022-04-15 07:55:45 +10:00
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// An unspecified value is returned that should be adequate in most
/// situations.
fn incoming_packet_capacity(&self) -> usize {
2022-09-02 17:06:45 +10:00
64
2022-04-15 07:55:45 +10:00
}
/// Called once at startup to get the capacity of the buffer used to
/// hold outgoing packets.
2022-04-15 07:55:45 +10:00
///
2022-09-02 17:06:45 +10:00
/// A larger capacity reduces the chance that a client needs to be
/// disconnected due to a full buffer, but increases potential memory usage.
2022-04-15 07:55:45 +10:00
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// An unspecified value is returned that should be adequate in most
/// situations.
fn outgoing_packet_capacity(&self) -> usize {
2022-06-20 01:40:37 +10:00
2048
2022-04-15 07:55:45 +10:00
}
/// Called once at startup to get a handle to the tokio runtime the server
/// will use.
2022-04-15 07:55:45 +10:00
///
/// If a handle is not provided, the server will create its own tokio
/// runtime.
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// Returns `None`.
fn tokio_handle(&self) -> Option<TokioHandle> {
None
2022-04-15 07:55:45 +10:00
}
/// Called once at startup to get the list of [`Dimension`]s usable on the
/// server.
2022-04-15 07:55:45 +10:00
///
2022-07-11 22:08:02 +10:00
/// The dimensions returned by [`SharedServer::dimensions`] will be in the
/// same order as the `Vec` returned by this function.
///
2022-07-11 22:08:02 +10:00
/// The number of elements in the returned `Vec` must be in `1..=u16::MAX`.
2022-04-15 07:55:45 +10:00
/// Additionally, the documented requirements on the fields of [`Dimension`]
/// must be met.
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// Returns `vec![Dimension::default()]`.
fn dimensions(&self) -> Vec<Dimension> {
vec![Dimension::default()]
2022-04-15 07:55:45 +10:00
}
/// Called once at startup to get the list of [`Biome`]s usable on the
/// server.
2022-04-15 07:55:45 +10:00
///
2022-07-11 22:08:02 +10:00
/// The biomes returned by [`SharedServer::biomes`] will be in the same
/// order as the `Vec` returned by this function.
///
2022-07-11 22:08:02 +10:00
/// The number of elements in the returned `Vec` must be in `1..=u16::MAX`.
2022-04-15 07:55:45 +10:00
/// Additionally, the documented requirements on the fields of [`Biome`]
/// must be met.
2022-04-15 07:55:45 +10:00
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// Returns `vec![Dimension::default()]`.
fn biomes(&self) -> Vec<Biome> {
vec![Biome::default()]
2022-04-15 07:55:45 +10:00
}
/// Called when the server receives a Server List Ping query.
/// Data for the response can be provided or the query can be ignored.
2022-04-15 07:55:45 +10:00
///
/// This method is called from within a tokio runtime.
///
2022-04-15 07:55:45 +10:00
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// The query is ignored.
async fn server_list_ping(
&self,
2022-07-16 13:40:39 +10:00
shared: &SharedServer<Self>,
remote_addr: SocketAddr,
2022-08-15 08:18:22 +10:00
protocol_version: i32,
) -> ServerListPing {
ServerListPing::Ignore
}
2022-04-15 07:55:45 +10:00
/// Called asynchronously for each client after successful authentication
2022-07-11 22:08:02 +10:00
/// (if online mode is enabled) to determine if they can join
/// the server. On success, the new client is added to the server's
/// [`Clients`]. If this method returns with `Err(reason)`, then the
/// client is immediately disconnected with the given reason.
2022-04-15 07:55:45 +10:00
///
/// This method is the appropriate place to perform asynchronous
/// operations such as database queries which may take some time to
/// complete.
2022-04-15 07:55:45 +10:00
///
/// This method is called from within a tokio runtime.
///
2022-04-15 07:55:45 +10:00
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// The client is allowed to join unconditionally.
2022-07-11 22:08:02 +10:00
///
/// [`Clients`]: crate::client::Clients
2022-07-16 13:40:39 +10:00
async fn login(&self, shared: &SharedServer<Self>, ncd: &NewClientData) -> Result<(), Text> {
Ok(())
}
2022-04-15 07:55:45 +10:00
/// Called after the server is created, but prior to accepting connections
/// and entering the update loop.
2022-04-15 07:55:45 +10:00
///
/// This is useful for performing initialization work with a guarantee that
/// no connections to the server will be made until this function returns.
///
/// This method is called from within a tokio runtime.
2022-07-16 13:40:39 +10:00
fn init(&self, server: &mut Server<Self>) {}
2022-04-15 07:55:45 +10:00
/// Called once at the beginning of every server update (also known as
2022-07-11 22:08:02 +10:00
/// "tick"). This is likely where the majority of your code will be.
2022-04-15 07:55:45 +10:00
///
2022-07-11 22:08:02 +10:00
/// The frequency of ticks can be configured by [`Self::tick_rate`].
///
/// This method is called from within a tokio runtime.
2022-04-15 07:55:45 +10:00
///
/// # Default Implementation
2022-07-11 22:08:02 +10:00
///
/// The default implementation does nothing.
2022-07-16 13:40:39 +10:00
fn update(&self, server: &mut Server<Self>);
2022-04-15 07:55:45 +10:00
}
2022-07-11 22:08:02 +10:00
/// The result of the [`server_list_ping`](Config::server_list_ping) callback.
2022-09-08 04:36:12 +10:00
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug)]
pub enum ServerListPing<'a> {
2022-04-15 07:55:45 +10:00
/// Responds to the server list ping with the given information.
Respond {
2022-07-11 22:08:02 +10:00
/// Displayed as the number of players on the server.
2022-04-15 07:55:45 +10:00
online_players: i32,
2022-07-11 22:08:02 +10:00
/// Displayed as the maximum number of players allowed on the server at
/// a time.
2022-04-15 07:55:45 +10:00
max_players: i32,
/// The list of players visible by hovering over the player count.
///
/// Has no effect if this list is empty.
player_sample: Cow<'a, [PlayerSampleEntry<'a>]>,
2022-07-11 22:08:02 +10:00
/// A description of the server.
2022-04-15 07:55:45 +10:00
description: Text,
/// The server's icon as the bytes of a PNG image.
/// The image must be 64x64 pixels.
///
/// No icon is used if the value is `None`.
favicon_png: Option<Cow<'a, [u8]>>,
2022-04-15 07:55:45 +10:00
},
/// Ignores the query and disconnects from the client.
Ignore,
}
/// Represents an individual entry in the player sample.
#[derive(Clone, Debug, Serialize)]
pub struct PlayerSampleEntry<'a> {
/// The name of the player.
///
/// This string can contain
/// [legacy formatting codes](https://minecraft.fandom.com/wiki/Formatting_codes).
pub name: Cow<'a, str>,
/// The player UUID.
pub id: Uuid,
}