Update rust docs

This commit is contained in:
Ryan 2022-09-02 00:06:45 -07:00
parent 5d8f7a49da
commit f7a35f356e
14 changed files with 174 additions and 158 deletions

View file

@ -37,7 +37,7 @@ sha2 = "0.10"
thiserror = "1"
url = { version = "2.2.2", features = ["serde"] }
uuid = "1"
valence_nbt = { path = "valence_nbt" }
serde_nbt = { path = "serde_nbt" }
vek = "0.15"
[dependencies.tokio]
@ -68,4 +68,4 @@ num = "0.4"
protocol = []
[workspace]
members = ["valence_nbt", "packet_inspector"]
members = ["serde_nbt", "packet_inspector"]

View file

@ -23,7 +23,7 @@ use crate::protocol::packets::s2c::play::{
use crate::protocol::{Encode, NbtBridge, VarInt, VarLong};
use crate::server::SharedServer;
/// A container for all [`Chunks`]s in a [`World`](crate::world::World).
/// A container for all [`Chunk`]s in a [`World`](crate::world::World).
pub struct Chunks<C: Config> {
chunks: HashMap<ChunkPos, Chunk<C>>,
shared: SharedServer<C>,
@ -65,8 +65,8 @@ impl<C: Config> Chunks<C> {
/// Removes a chunk at the provided position.
///
/// If a chunk exists at the position, then it is deleted and `true` is
/// returned. Otherwise, `false` is returned.
/// If a chunk exists at the position, then it is deleted and its
/// `ChunkState` is returned. Otherwise, `None` is returned.
pub fn remove(&mut self, pos: impl Into<ChunkPos>) -> Option<C::ChunkState> {
self.chunks.remove(&pos.into()).map(|c| c.state)
}
@ -90,6 +90,9 @@ impl<C: Config> Chunks<C> {
self.chunks.get_mut(&pos.into())
}
/// Removes all chunks for which `f` returns `true`.
///
/// All chunks are visited in an unspecified order.
pub fn retain(&mut self, mut f: impl FnMut(ChunkPos, &mut Chunk<C>) -> bool) {
self.chunks.retain(|&pos, chunk| f(pos, chunk))
}
@ -99,8 +102,8 @@ impl<C: Config> Chunks<C> {
self.chunks.clear();
}
/// Returns an immutable iterator over all chunks in the world in an
/// unspecified order.
/// Returns an iterator over all chunks in the world in an unspecified
/// order.
pub fn iter(
&self,
) -> impl ExactSizeIterator<Item = (ChunkPos, &Chunk<C>)> + FusedIterator + Clone + '_ {
@ -115,7 +118,7 @@ impl<C: Config> Chunks<C> {
self.chunks.iter_mut().map(|(&pos, chunk)| (pos, chunk))
}
/// Returns a parallel immutable iterator over all chunks in the world in an
/// Returns a parallel iterator over all chunks in the world in an
/// unspecified order.
pub fn par_iter(&self) -> impl ParallelIterator<Item = (ChunkPos, &Chunk<C>)> + Clone + '_ {
self.chunks.par_iter().map(|(&pos, chunk)| (pos, chunk))
@ -131,9 +134,8 @@ impl<C: Config> Chunks<C> {
///
/// If the position is not inside of a chunk, then `None` is returned.
///
/// Note: if you need to get a large number of blocks, it may be more
/// efficient to read from the chunks directly with
/// [`Chunk::get_block_state`].
/// Note: if you need to get a large number of blocks, it is more efficient
/// to read from the chunks directly with [`Chunk::get_block_state`].
pub fn get_block_state(&self, pos: impl Into<BlockPos>) -> Option<BlockState> {
let pos = pos.into();
let chunk_pos = ChunkPos::from(pos);
@ -243,28 +245,41 @@ impl<C: Config> Chunk<C> {
chunk
}
/// Returns `true` if this chunk was created during the current tick.
pub fn created_this_tick(&self) -> bool {
self.created_this_tick
}
/// Returns the height of this chunk in blocks.
pub fn height(&self) -> usize {
self.sections.len() * 16
}
/// Gets the block state at the provided offsets in the chunk.
///
/// # Panics
///
/// Panics if the offsets are outside the bounds of the chunk.
pub fn get_block_state(&self, x: usize, y: usize, z: usize) -> BlockState {
if x < 16 && y < self.height() && z < 16 {
assert!(
x < 16 && y < self.height() && z < 16,
"chunk block offsets must be within bounds"
);
BlockState::from_raw_unchecked(
self.sections[y / 16].blocks[x + z * 16 + y % 16 * 16 * 16] & BLOCK_STATE_MASK,
)
} else {
BlockState::AIR
}
}
/// Sets the block state at the provided offsets in the chunk.
///
/// # Panics
///
/// Panics if the offsets are outside the bounds of the chunk.
pub fn set_block_state(&mut self, x: usize, y: usize, z: usize, block: BlockState) {
assert!(
x < 16 && y < self.height() && z < 16,
"the chunk block coordinates must be within bounds"
"chunk block offsets must be within bounds"
);
let sect = &mut self.sections[y / 16];
@ -282,18 +297,35 @@ impl<C: Config> Chunk<C> {
}
}
/// Gets the biome at the provided biome offsets in the chunk.
///
/// Note: the arguments are **not** block positions. Biomes are 4x4x4
/// segments of a chunk, so `x` and `z` are in `0..=4`.
///
/// # Panics
///
/// Panics if the offsets are outside the bounds of the chunk.
pub fn get_biome(&self, x: usize, y: usize, z: usize) -> BiomeId {
if x < 4 && y < self.height() / 4 && z < 4 {
assert!(
x < 4 && y < self.height() / 4 && z < 4,
"chunk biome offsets must be within bounds"
);
self.sections[y / 4].biomes[x + z * 4 + y % 4 * 4 * 4]
} else {
BiomeId::default()
}
}
/// Sets the biome at the provided biome offsets in the chunk.
///
/// Note: the arguments are **not** block positions. Biomes are 4x4x4
/// segments of a chunk, so `x` and `z` are in `0..=4`.
///
/// # Panics
///
/// Panics if the offsets are outside the bounds of the chunk.
pub fn set_biome(&mut self, x: usize, y: usize, z: usize, b: BiomeId) {
assert!(
x < 4 && y < self.height() / 4 && z < 4,
"the chunk biome coordinates must be within bounds"
"chunk biome offsets must be within bounds"
);
self.sections[y / 4].biomes[x + z * 4 + y % 4 * 4 * 4] = b;

View file

@ -70,22 +70,22 @@ impl<C: Config> Clients<C> {
/// Removes a client from the server.
///
/// If the given client ID is valid, `true` is returned and the client is
/// deleted. Otherwise, `false` is returned and the function has no effect.
/// If the given client ID is valid, the client's `ClientState` is returned
/// and the client is deleted. Otherwise, `None` is returned and the
/// function has no effect.
pub fn remove(&mut self, client: ClientId) -> Option<C::ClientState> {
self.slab.remove(client.0).map(|c| c.state)
}
/// Deletes all clients from the server for
/// which `f` returns `true`.
/// Deletes all clients from the server for which `f` returns `true`.
///
/// All clients are visited in an unspecified order.
pub fn retain(&mut self, mut f: impl FnMut(ClientId, &mut Client<C>) -> bool) {
self.slab.retain(|k, v| f(ClientId(k), v))
}
/// Returns the number of clients on the server. This includes clients
/// which may be disconnected.
/// Returns the number of clients on the server. This includes clients for
/// which [`Client::is_disconnected`] returns true.
pub fn len(&self) -> usize {
self.slab.len()
}
@ -102,8 +102,8 @@ impl<C: Config> Clients<C> {
self.slab.get_mut(client.0)
}
/// Returns an immutable iterator over all clients on the server in an
/// unspecified order.
/// Returns an iterator over all clients on the server in an unspecified
/// order.
pub fn iter(
&self,
) -> impl ExactSizeIterator<Item = (ClientId, &Client<C>)> + FusedIterator + Clone + '_ {
@ -118,8 +118,8 @@ impl<C: Config> Clients<C> {
self.slab.iter_mut().map(|(k, v)| (ClientId(k), v))
}
/// Returns a parallel immutable iterator over all clients on the server in
/// an unspecified order.
/// Returns a parallel iterator over all clients on the server in an
/// unspecified order.
pub fn par_iter(&self) -> impl ParallelIterator<Item = (ClientId, &Client<C>)> + Clone + '_ {
self.slab.par_iter().map(|(k, v)| (ClientId(k), v))
}
@ -170,7 +170,9 @@ impl ClientId {
/// simply a subtype of the entity base class backed by a remote connection.
///
/// In Valence however, clients and players are decoupled. This separation
/// allows for greater flexibility and parallelism.
/// allows for greater flexibility and enables parallelism.
///
/// [`Entity`]: crate::entity::Entity
pub struct Client<C: Config> {
/// Custom state.
pub state: C::ClientState,
@ -301,7 +303,7 @@ impl<C: Config> Client<C> {
self.uuid
}
/// Gets the username of this client, which is always valid.
/// Gets the username of this client.
pub fn username(&self) -> &str {
&self.username
}
@ -317,18 +319,22 @@ impl<C: Config> Client<C> {
self.world
}
/// Gets the player list this client sees.
pub fn player_list(&self) -> Option<&PlayerListId> {
self.new_player_list.as_ref()
}
pub fn set_player_list(&mut self, id: Option<PlayerListId>) -> Option<PlayerListId> {
mem::replace(&mut self.new_player_list, id)
/// Sets the player list this client sees.
///
/// The previous player list ID is returned.
pub fn set_player_list(&mut self, id: impl Into<Option<PlayerListId>>) -> Option<PlayerListId> {
mem::replace(&mut self.new_player_list, id.into())
}
/// Sets if this client sees the world as superflat. Superflat worlds have
/// a horizon line lower than normal worlds.
///
/// The player must be spawned for changes to take effect.
/// The player must be (re)spawned for changes to take effect.
pub fn set_flat(&mut self, flat: bool) {
self.bits.set_flat(flat);
}
@ -349,7 +355,8 @@ impl<C: Config> Client<C> {
self.bits.set_spawn(true);
}
/// Sends a system message to the player which is visible in the chat.
/// Sends a system message to the player which is visible in the chat. The
/// message is only visible to this client.
pub fn send_message(&mut self, msg: impl Into<Text>) {
// We buffer messages because weird things happen if we send them before the
// login packet.
@ -512,6 +519,8 @@ impl<C: Config> Client<C> {
self.send.is_none()
}
/// Returns an iterator over all pending client events in the order they
/// will be removed from the queue.
pub fn events(
&self,
) -> impl DoubleEndedIterator<Item = &ClientEvent> + ExactSizeIterator + FusedIterator + Clone + '_
@ -519,7 +528,7 @@ impl<C: Config> Client<C> {
self.events.iter()
}
/// Removes an [`Event`] from the event queue.
/// Removes a [`ClientEvent`] from the event queue.
///
/// If there are no remaining events, `None` is returned.
///
@ -529,6 +538,7 @@ impl<C: Config> Client<C> {
self.events.pop_front()
}
/// Pushes an entity event to the queue.
pub fn push_entity_event(&mut self, event: EntityEvent) {
self.entity_events.push(event);
}

View file

@ -15,12 +15,13 @@ use crate::{Ticks, STANDARD_TPS};
/// A trait for the configuration of a server.
///
/// This trait uses the [async_trait] attribute macro. It is exported at the
/// root of this crate.
/// root of this crate. async_trait will be removed once async fns in traits
/// are stabilized.
///
/// [async_trait]: https://docs.rs/async-trait/latest/async_trait/
#[async_trait]
#[allow(unused_variables)]
pub trait Config: 'static + Sized + Send + Sync + UnwindSafe + RefUnwindSafe {
pub trait Config: Sized + Send + Sync + UnwindSafe + RefUnwindSafe + 'static {
/// Custom state to store with the [`Server`].
type ServerState: Send + Sync;
/// Custom state to store with every [`Client`](crate::client::Client).
@ -93,22 +94,22 @@ pub trait Config: 'static + Sized + Send + Sync + UnwindSafe + RefUnwindSafe {
/// Called once at startup to get the capacity of the buffer used to
/// hold incoming packets.
///
/// A larger capacity reduces the chance of packet loss but increases
/// potential memory usage.
/// A larger capacity reduces the chance that a client needs to be
/// disconnected due to a full buffer, but increases potential memory usage.
///
/// # Default Implementation
///
/// An unspecified value is returned that should be adequate in most
/// situations.
fn incoming_packet_capacity(&self) -> usize {
32
64
}
/// Called once at startup to get the capacity of the buffer used to
/// hold outgoing packets.
///
/// A larger capacity reduces the chance of packet loss due to a full buffer
/// but increases potential memory usage.
/// A larger capacity reduces the chance that a client needs to be
/// disconnected due to a full buffer, but increases potential memory usage.
///
/// # Default Implementation
///

View file

@ -1,4 +1,4 @@
//! Dynamic actors in a world.
//! Entities in a world.
use std::collections::hash_map::Entry;
use std::collections::HashMap;
@ -26,7 +26,7 @@ pub mod types;
include!(concat!(env!("OUT_DIR"), "/entity_event.rs"));
/// A container for all [`Entity`]s on a [`Server`](crate::server::Server).
/// A container for all [`Entity`]s on a server.
///
/// # Spawning Player Entities
///
@ -34,7 +34,7 @@ include!(concat!(env!("OUT_DIR"), "/entity_event.rs"));
/// entity to be visible to clients, the player's UUID must be added to the
/// [`PlayerList`] _before_ being loaded by the client.
///
/// [`Player`]: crate::entity::types::Player
/// [`Player`]: crate::entity::data::Player
/// [`PlayerList`]: crate::player_list::PlayerList
pub struct Entities<C: Config> {
slab: VersionedSlab<Entity<C>>,
@ -62,7 +62,7 @@ impl<C: Config> Entities<C> {
.expect("UUID collision")
}
/// Like [`Self::create`], but requires specifying the new
/// Like [`Self::insert`], but requires specifying the new
/// entity's UUID.
///
/// The provided UUID must not conflict with an existing entity UUID. If it
@ -103,8 +103,9 @@ impl<C: Config> Entities<C> {
/// Removes an entity from the server.
///
/// If the given entity ID is valid, `true` is returned and the entity is
/// deleted. Otherwise, `false` is returned and the function has no effect.
/// If the given entity ID is valid, the entity's `EntityState` is returned
/// and the entity is deleted. Otherwise, `None` is returned and the
/// function has no effect.
pub fn remove(&mut self, entity: EntityId) -> Option<C::EntityState> {
self.slab.remove(entity.0).map(|e| {
self.uuid_to_entity
@ -173,8 +174,8 @@ impl<C: Config> Entities<C> {
Some(EntityId(Key::new(index, version)))
}
/// Returns an immutable iterator over all entities on the server in an
/// unspecified order.
/// Returns an iterator over all entities on the server in an unspecified
/// order.
pub fn iter(
&self,
) -> impl ExactSizeIterator<Item = (EntityId, &Entity<C>)> + FusedIterator + Clone + '_ {
@ -189,8 +190,8 @@ impl<C: Config> Entities<C> {
self.slab.iter_mut().map(|(k, v)| (EntityId(k), v))
}
/// Returns a parallel immutable iterator over all entities on the server in
/// an unspecified order.
/// Returns a parallel iterator over all entities on the server in an
/// unspecified order.
pub fn par_iter(&self) -> impl ParallelIterator<Item = (EntityId, &Entity<C>)> + Clone + '_ {
self.slab.par_iter().map(|(k, v)| (EntityId(k), v))
}
@ -239,7 +240,7 @@ impl EntityId {
/// Represents an entity on the server.
///
/// In essence, an entity is anything in a world that isn't a block or client.
/// An entity is mostly anything in a world that isn't a block or client.
/// Entities include paintings, falling blocks, zombies, fireballs, and more.
///
/// Every entity has common state which is accessible directly from
@ -277,10 +278,12 @@ impl<C: Config> Entity<C> {
self.bits
}
/// Returns a shared reference to this entity's tracked data.
pub fn data(&self) -> &TrackedData {
&self.variants
}
/// Returns an exclusive reference to this entity's tracked data.
pub fn data_mut(&mut self) -> &mut TrackedData {
&mut self.variants
}
@ -290,6 +293,7 @@ impl<C: Config> Entity<C> {
self.variants.kind()
}
/// Triggers an entity event for this entity.
pub fn push_event(&mut self, event: EntityEvent) {
self.events.push(event);
}
@ -411,7 +415,7 @@ impl<C: Config> Entity<C> {
/// The hitbox of an entity is determined by its position, entity type, and
/// other state specific to that type.
///
/// [interact event]: crate::client::EntityEvent::InteractWithEntity
/// [interact event]: crate::client::ClientEvent::InteractWithEntity
pub fn hitbox(&self) -> Aabb<f64> {
let dims = match &self.variants {
TrackedData::Allay(_) => [0.6, 0.35, 0.6],

View file

@ -11,13 +11,14 @@ use thiserror::Error;
use crate::protocol::{encode_string_bounded, BoundedString, Decode, Encode};
/// An identifier is a string split into a "namespace" part and a "name" part.
/// An identifier is a string split into a "namespace" part and a "path" part.
/// For instance `minecraft:apple` and `apple` are both valid identifiers.
///
/// If the namespace part is left off (the part before and including the colon)
/// the namespace is considered to be "minecraft" for the purposes of equality.
///
/// The identifier must match the regex `^([a-z0-9_-]+:)?[a-z0-9_\/.-]+$`.
/// A string must match the regex `^([a-z0-9_-]+:)?[a-z0-9_\/.-]+$` to be a
/// valid identifier.
#[derive(Clone, Eq)]
pub struct Ident {
ident: Cow<'static, AsciiStr>,
@ -90,6 +91,7 @@ impl Ident {
}
/// Returns the namespace part of this namespaced identifier.
///
/// If this identifier was constructed from a string without a namespace,
/// then `None` is returned.
pub fn namespace(&self) -> Option<&str> {
@ -100,8 +102,8 @@ impl Ident {
}
}
/// Returns the name part of this namespaced identifier.
pub fn name(&self) -> &str {
/// Returns the path part of this namespaced identifier.
pub fn path(&self) -> &str {
if self.colon_idx == usize::MAX {
self.ident.as_str()
} else {
@ -188,14 +190,14 @@ impl std::fmt::Display for Ident {
impl PartialEq for Ident {
fn eq(&self, other: &Self) -> bool {
self.namespace().unwrap_or("minecraft") == other.namespace().unwrap_or("minecraft")
&& self.name() == other.name()
&& self.path() == other.path()
}
}
impl std::hash::Hash for Ident {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.namespace().unwrap_or("minecraft").hash(state);
self.name().hash(state);
self.path().hash(state);
}
}
@ -261,7 +263,7 @@ impl<'de> Visitor<'de> for IdentifierVisitor {
/// let apple = ident!("{namespace}:apple");
///
/// assert_eq!(apple.namespace(), Some("my_namespace"));
/// assert_eq!(apple.name(), "apple");
/// assert_eq!(apple.path(), "apple");
/// ```
#[macro_export]
macro_rules! ident {

View file

@ -1,21 +1,20 @@
//! A Rust framework for building Minecraft servers.
//!
//! Valence is a Rust library which provides the necessary abstractions over
//! Minecraft's protocol to build servers. Very few assumptions about the
//! desired server are made, which allows for greater flexibility in its design.
//!
//! At a high level, a Valence [`Server`] is a collection of [`Clients`],
//! [`Entities`], and [`Worlds`]. When a client connects to the server, they are
//! added to the server's [`Clients`]. After connecting, clients are assigned to
//! a [`World`] where they are able to interact with the entities and
//! [`Chunks`] that are a part of it.
//! [`Entities`], and [`Worlds`]. When a client connects to the server they are
//! added to the collection of `Clients`. After connecting, clients should
//! be assigned to a [`World`] where they can interact with the entities
//! and [`Chunks`] that are a part of it.
//!
//! The Valence documentation assumes some familiarity with Minecraft and its
//! mechanics. See the [Minecraft Wiki] for general information and [wiki.vg]
//! for protocol documentation.
//!
//! For more information, see the repository [README].
//!
//! [Minecraft Wiki]: https://minecraft.fandom.com/wiki/Minecraft_Wiki
//! [wiki.vg]: https://wiki.vg/Main_Page
//! [README]: https://github.com/rj00a/valence
//!
//! # Logging
//!
@ -35,58 +34,16 @@
//! **You must not call [`mem::swap`] on these references (or any other
//! function that would move their location in memory).** Doing so breaks
//! invariants within the library and the resulting behavior is safe but
//! unspecified. These types should be considered [pinned](std::pin).
//! unspecified. You can think of these types as being [pinned](std::pin).
//!
//! Preventing this illegal behavior using Rust's type system was considered too
//! cumbersome, so a note has been left here instead.
//! cumbersome, so this note has been left here instead.
//!
//! [`mem::swap`]: std::mem::swap
//!
//! # Examples
//!
//! The following is a minimal server implementation. You should be able to
//! connect to the server at `localhost`.
//!
//! ```
//! use valence::config::Config;
//! use valence::server::{Server, ShutdownResult};
//!
//! pub fn main() -> ShutdownResult {
//! valence::start_server(Game, ())
//! }
//!
//! struct Game;
//!
//! impl Config for Game {
//! type ServerState = ();
//! type ClientState = ();
//! type EntityState = ();
//! type WorldState = ();
//! type ChunkState = ();
//!
//! fn max_connections(&self) -> usize {
//! 256
//! }
//!
//! fn update(&self, server: &mut Server<Self>) {
//! server.clients.retain(|_, client| {
//! if client.created_tick() == server.shared.current_tick() {
//! println!("{} joined!", client.username());
//! }
//!
//! if client.is_disconnected() {
//! println!("{} left!", client.username());
//! false
//! } else {
//! true
//! }
//! });
//! # server.shared.shutdown::<_, std::convert::Infallible>(Ok(()));
//! }
//! }
//! ```
//!
//! For more complete examples, see the [examples] in the source repository.
//! See the [examples] directory in the source repository.
//!
//! [examples]: https://github.com/rj00a/valence/tree/main/examples
//!
@ -122,7 +79,7 @@ pub use async_trait::async_trait;
#[doc(inline)]
pub use server::start_server;
#[doc(inline)]
pub use {uuid, valence_nbt as nbt, vek};
pub use {serde_nbt as nbt, uuid, vek};
pub mod biome;
pub mod block;

View file

@ -17,10 +17,19 @@ use crate::protocol::VarInt;
use crate::slab_rc::{Key, SlabRc};
use crate::text::Text;
/// A container for all [`PlayerList`]s on a server.
pub struct PlayerLists<C: Config> {
slab: SlabRc<PlayerList<C>>,
}
/// An identifier for a [`PlayerList`] on the server.
///
/// Player list IDs are refcounted. Once all IDs referring to the same player
/// list are dropped, the player list is automatically deleted.
///
/// The [`Ord`] instance on this type is correct but otherwise unspecified. This
/// is useful for storing IDs in containers such as
/// [`BTreeMap`](std::collections::BTreeMap).
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct PlayerListId(Key);
@ -31,6 +40,7 @@ impl<C: Config> PlayerLists<C> {
}
}
///
pub fn insert(&mut self, state: C::PlayerListState) -> (PlayerListId, &mut PlayerList<C>) {
let (key, pl) = self.slab.insert(PlayerList {
state,
@ -199,8 +209,7 @@ impl<C: Config> PlayerList<C> {
self.entries.iter().map(|(k, v)| (*k, v))
}
/// Returns an iterator which allows modifications over all entries. The
/// entries are visited in an unspecified order.
/// Returns a mutable iterator over all entries in an unspecified order.
pub fn entries_mut(&mut self) -> impl Iterator<Item = (Uuid, &mut PlayerListEntry)> + '_ {
self.entries.iter_mut().map(|(k, v)| (*k, v))
}

View file

@ -1,6 +1,6 @@
//! Provides low-level access to the Minecraft protocol.
//!
//! Hopefully you will not need to use this module.
//! You should avoid this module if possible.
use std::io::{Read, Write};
use std::mem;

View file

@ -49,9 +49,6 @@ pub trait DecodePacket: Sized + fmt::Debug {
///
/// The fields of the struct are encoded and decoded in the order they are
/// defined.
///
/// If a packet ID is provided after the struct name, then this struct will
/// implement [`EncodePacket`] and [`DecodePacket`].
macro_rules! def_struct {
(
$(#[$struct_attrs:meta])*
@ -110,9 +107,6 @@ macro_rules! def_struct {
///
/// The enum tag is encoded and decoded first, followed by the appropriate
/// variant.
///
/// If a packet ID is provided after the struct name, then this struct will
/// implement [`EncodePacket`] and [`DecodePacket`].
macro_rules! def_enum {
(
$(#[$enum_attrs:meta])*
@ -195,6 +189,7 @@ macro_rules! if_typ_is_empty_pat {
};
}
/// Defines a bitfield struct which implements [`Encode`] and [`Decode`].
macro_rules! def_bitfield {
(
$(#[$struct_attrs:meta])*
@ -273,6 +268,10 @@ macro_rules! def_bitfield {
}
}
/// Defines an enum of packets.
///
/// An impl for [`EncodePacket`] and [`DecodePacket`] is defined for each
/// supplied packet.
macro_rules! def_packet_group {
(
$(#[$attrs:meta])*

View file

@ -36,9 +36,7 @@ use crate::player_list::PlayerLists;
use crate::player_textures::SignedPlayerTextures;
use crate::protocol::codec::{Decoder, Encoder};
use crate::protocol::packets::c2s::handshake::{Handshake, HandshakeNextState};
use crate::protocol::packets::c2s::login::{
EncryptionResponse, LoginStart, VerifyTokenOrMsgSig,
};
use crate::protocol::packets::c2s::login::{EncryptionResponse, LoginStart, VerifyTokenOrMsgSig};
use crate::protocol::packets::c2s::play::C2sPlayPacket;
use crate::protocol::packets::c2s::status::{QueryPing, QueryRequest};
use crate::protocol::packets::s2c::login::{
@ -59,13 +57,13 @@ pub struct Server<C: Config> {
pub state: C::ServerState,
/// A handle to this server's [`SharedServer`].
pub shared: SharedServer<C>,
/// All of the clients in the server.
/// All of the clients on the server.
pub clients: Clients<C>,
/// All of entities in the server.
/// All of entities on the server.
pub entities: Entities<C>,
/// All of the worlds in the server.
/// All of the worlds on the server.
pub worlds: Worlds<C>,
/// All of the player lists in the server.
/// All of the player lists on the server.
pub player_lists: PlayerLists<C>,
}
@ -221,6 +219,10 @@ impl<C: Config> SharedServer<C> {
}
/// Obtains a [`Biome`] by using its corresponding [`BiomeId`].
///
/// It is safe but unspecified behavior to call this function using a
/// [`BiomeId`] not originating from the configuration used to construct
/// the server.
pub fn biome(&self, id: BiomeId) -> &Biome {
self.0.biomes.get(id.0 as usize).expect("invalid biome ID")
}

View file

@ -16,7 +16,7 @@ use crate::world::WorldId;
///
/// The spatial index is only updated at the end of each tick. Any modification
/// to an entity that would change its hitbox is not reflected in the spatial
/// index until the end of the tick.
/// index until the next tick.
///
/// [hitboxes]: crate::entity::Entity::hitbox
pub struct SpatialIndex {
@ -28,9 +28,9 @@ impl SpatialIndex {
Self { bvh: Bvh::new() }
}
/// This is for tests only! Not part of the public API.
#[doc(hidden)]
#[deprecated = "This is for documentation tests only!"]
pub fn example_new() -> Self {
pub fn test_new() -> Self {
dbg!("Don't call me from outside tests!");
Self::new()
}
@ -50,8 +50,7 @@ impl SpatialIndex {
/// Visit all entities intersecting a 10x10x10 cube centered at the origin.
///
/// ```
/// # #[allow(deprecated)]
/// # let si = valence::spatial_index::SpatialIndex::example_new();
/// # let si = valence::spatial_index::SpatialIndex::test_new();
/// use valence::vek::*;
///
/// let cube = Aabb {
@ -104,9 +103,9 @@ impl SpatialIndex {
/// Casts a ray defined by `origin` and `direction` through entity hitboxes
/// and returns the closest intersection for which `f` returns `true`.
///
/// `f` is a predicate which can be used to filter intersections. For
/// instance, if a ray is shot from a player's eye position, you probably
/// don't want the ray to intersect with the player's own hitbox.
/// `f` is a predicate used to filter intersections. For instance, if a ray
/// is shot from a player's eye position, you probably don't want the
/// ray to intersect with the player's own hitbox.
///
/// If no intersections are found or if `f` never returns `true` then `None`
/// is returned. Additionally, the given ray direction must be
@ -115,8 +114,7 @@ impl SpatialIndex {
/// # Examples
///
/// ```
/// # #[allow(deprecated)]
/// # let si = valence::spatial_index::SpatialIndex::example_new();
/// # let si = valence::spatial_index::SpatialIndex::test_new();
/// use valence::vek::*;
///
/// let origin = Vec3::new(0.0, 0.0, 0.0);

View file

@ -17,7 +17,7 @@ use crate::protocol::{BoundedString, Decode, Encode};
///
/// For more information, see the relevant [Minecraft Wiki article].
///
/// Note that the current `Deserialize` implementation on this type recognizes
/// Note that the current [`Deserialize`] implementation on this type recognizes
/// only a subset of the full JSON chat component format.
///
/// [Minecraft Wiki article]: https://minecraft.fandom.com/wiki/Raw_JSON_text_format

View file

@ -57,15 +57,17 @@ impl<C: Config> Worlds<C> {
/// Deletes a world from the server.
///
/// Note that entities located in the world are not deleted themselves.
/// Additionally, any clients that are still in the deleted world at the end
/// Note that any entities located in the world are not deleted.
/// Additionally, clients that are still in the deleted world at the end
/// of the tick are disconnected.
///
/// Returns `true` if the world was deleted. Otherwise, `false` is returned
/// and the function has no effect.
pub fn remove(&mut self, world: WorldId) -> bool {
self.slab.remove(world.0).is_some()
}
/// Deletes all worlds from the server (as if by [`Self::delete`]) for which
/// `f` returns `true`.
/// Removes all worlds from the server for which `f` returns `true`.
///
/// All worlds are visited in an unspecified order.
pub fn retain(&mut self, mut f: impl FnMut(WorldId, &mut World<C>) -> bool) {
@ -89,8 +91,8 @@ impl<C: Config> Worlds<C> {
self.slab.get_mut(world.0)
}
/// Returns an immutable iterator over all worlds on the server in an
/// unspecified order.
/// Returns an iterator over all worlds on the server in an unspecified
/// order.
pub fn iter(
&self,
) -> impl ExactSizeIterator<Item = (WorldId, &World<C>)> + FusedIterator + Clone + '_ {
@ -105,8 +107,8 @@ impl<C: Config> Worlds<C> {
self.slab.iter_mut().map(|(k, v)| (WorldId(k), v))
}
/// Returns a parallel immutable iterator over all worlds on the server in
/// an unspecified order.
/// Returns a parallel iterator over all worlds on the server in an
/// unspecified order.
pub fn par_iter(&self) -> impl ParallelIterator<Item = (WorldId, &World<C>)> + Clone + '_ {
self.slab.par_iter().map(|(k, v)| (WorldId(k), v))
}
@ -130,7 +132,7 @@ pub struct World<C: Config> {
pub meta: WorldMeta,
}
/// Contains miscellaneous world state.
/// Contains miscellaneous data about the world.
pub struct WorldMeta {
dimension: DimensionId,
}