mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-11 07:11:30 +11:00
Clean up docs and fix clippy issues
This commit is contained in:
parent
c5f0f6024c
commit
4b83801066
|
@ -2160,7 +2160,7 @@ pub fn build() -> anyhow::Result<()> {
|
|||
|
||||
let mut all_classes = BTreeMap::new();
|
||||
for mut class in entities.iter().cloned() {
|
||||
while let None = all_classes.insert(class.name, class) {
|
||||
while all_classes.insert(class.name, class).is_none() {
|
||||
match class.inherit {
|
||||
Some(parent) => class = parent,
|
||||
None => break,
|
||||
|
@ -2227,8 +2227,8 @@ pub fn build() -> anyhow::Result<()> {
|
|||
.enumerate()
|
||||
.map(|(field_offset, field)| {
|
||||
let name = ident(field.name.to_snake_case());
|
||||
let getter_name = ident(format!("get_{}", name.to_string()));
|
||||
let setter_name = ident(format!("set_{}", name.to_string()));
|
||||
let getter_name = ident(format!("get_{name}"));
|
||||
let setter_name = ident(format!("set_{name}"));
|
||||
|
||||
let field_offset = field_offset as u32;
|
||||
|
||||
|
@ -2254,8 +2254,8 @@ pub fn build() -> anyhow::Result<()> {
|
|||
.map(|bf| {
|
||||
let bit_name = ident(bf.name.to_snake_case());
|
||||
|
||||
let getter_name = ident(format!("get_{}", bit_name.to_string()));
|
||||
let setter_name = ident(format!("set_{}", bit_name.to_string()));
|
||||
let getter_name = ident(format!("get_{bit_name}"));
|
||||
let setter_name = ident(format!("set_{bit_name}"));
|
||||
|
||||
let offset = bf.offset;
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ impl Config for Game {
|
|||
// TODO: hardcoded eye pos.
|
||||
let eye_pos = Vec3::new(player_pos.x, player_pos.y + 1.6, player_pos.z);
|
||||
|
||||
#[allow(clippy::significant_drop_in_scrutinee)]
|
||||
for (cow_id, p) in cows.iter().cloned().zip(fibonacci_spiral(cow_count)) {
|
||||
let cow = server.entities.get_mut(cow_id).expect("missing cow");
|
||||
let rotated = p * rot;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Biome definitions.
|
||||
//! Biome configuration and identification.
|
||||
|
||||
use crate::ident;
|
||||
use crate::ident::Ident;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Blocks and related types.
|
||||
|
||||
#![allow(clippy::all, missing_docs)]
|
||||
|
||||
use std::fmt::{self, Display};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Chunks and related types.
|
||||
|
||||
// TODO: https://github.com/rust-lang/rust/issues/88581 for div_ceil
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
|
|
|
@ -28,9 +28,9 @@ impl From<(i32, i32)> for ChunkPos {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<(i32, i32)> for ChunkPos {
|
||||
fn into(self) -> (i32, i32) {
|
||||
(self.x, self.z)
|
||||
impl From<ChunkPos> for (i32, i32) {
|
||||
fn from(pos: ChunkPos) -> Self {
|
||||
(pos.x, pos.z)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,9 @@ impl From<[i32; 2]> for ChunkPos {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<[i32; 2]> for ChunkPos {
|
||||
fn into(self) -> [i32; 2] {
|
||||
[self.x, self.z]
|
||||
impl From<ChunkPos> for [i32; 2] {
|
||||
fn from(pos: ChunkPos) -> Self {
|
||||
[pos.x, pos.z]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Connections to the server after logging in.
|
||||
|
||||
/// Contains the [`Event`] enum and related data types.
|
||||
mod event;
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
|
@ -118,7 +120,7 @@ impl Clients {
|
|||
}
|
||||
}
|
||||
|
||||
/// A key for a [`Client`] on the server.
|
||||
/// An identifier for a [`Client`] on the server.
|
||||
///
|
||||
/// Client IDs are either _valid_ or _invalid_. Valid client IDs point to
|
||||
/// clients that have not been deleted, while invalid IDs point to those that
|
||||
|
@ -138,8 +140,8 @@ impl ClientId {
|
|||
/// Represents a remote connection to a client after successfully logging in.
|
||||
///
|
||||
/// Much like an [`Entity`], clients posess a location, rotation, and UUID.
|
||||
/// Clients are handled separately from entities and are partially
|
||||
/// controlled by the library.
|
||||
/// However, clients are handled separately from entities and are partially
|
||||
/// managed by the library.
|
||||
///
|
||||
/// By default, clients have no influence over the worlds they reside in. They
|
||||
/// cannot break blocks, hurt entities, or see other clients. Interactions with
|
||||
|
@ -475,9 +477,11 @@ impl Client {
|
|||
self.send.is_none()
|
||||
}
|
||||
|
||||
/// Removes an [`Event`] from the queue.
|
||||
/// Removes an [`Event`] from the event queue.
|
||||
///
|
||||
/// Any remaining client events not popped are deleted at the end of the
|
||||
/// If there are no remaining events, `None` is returned.
|
||||
///
|
||||
/// Any remaining client events are deleted at the end of the
|
||||
/// current tick.
|
||||
pub fn pop_event(&mut self) -> Option<Event> {
|
||||
self.events.pop_front()
|
||||
|
@ -629,7 +633,6 @@ impl Client {
|
|||
self.username()
|
||||
);
|
||||
self.disconnect_no_reason();
|
||||
return;
|
||||
}
|
||||
}
|
||||
C2sPlayPacket::BlockEntityTagQuery(_) => {}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Configuration for the server.
|
||||
|
||||
use std::any::Any;
|
||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use std::panic::{RefUnwindSafe, UnwindSafe};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Dimension configuration and identification.
|
||||
|
||||
use crate::ident;
|
||||
use crate::protocol_inner::packets::play::s2c::DimensionType;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Dynamic actors in a world.
|
||||
|
||||
pub mod data;
|
||||
pub mod types;
|
||||
|
||||
|
@ -198,7 +200,7 @@ impl Entities {
|
|||
}
|
||||
}
|
||||
|
||||
/// A key for an [`Entity`] on the server.
|
||||
/// An identifier for an [`Entity`] on the server.
|
||||
///
|
||||
/// Entity IDs are either _valid_ or _invalid_. Valid entity IDs point to
|
||||
/// entities that have not been deleted, while invalid IDs point to those that
|
||||
|
@ -554,20 +556,20 @@ impl Entity {
|
|||
match &self.data {
|
||||
EntityData::Marker(_) => None,
|
||||
EntityData::ExperienceOrb(_) => {
|
||||
Some(EntitySpawnPacket::SpawnExperienceOrb(AddExperienceOrb {
|
||||
Some(EntitySpawnPacket::ExperienceOrb(AddExperienceOrb {
|
||||
entity_id: VarInt(this_id.to_network_id()),
|
||||
position: self.new_position,
|
||||
count: 0, // TODO
|
||||
}))
|
||||
}
|
||||
EntityData::Player(_) => Some(EntitySpawnPacket::SpawnPlayer(AddPlayer {
|
||||
EntityData::Player(_) => Some(EntitySpawnPacket::Player(AddPlayer {
|
||||
entity_id: VarInt(this_id.to_network_id()),
|
||||
player_uuid: self.uuid,
|
||||
position: self.new_position,
|
||||
yaw: ByteAngle::from_degrees(self.yaw),
|
||||
pitch: ByteAngle::from_degrees(self.pitch),
|
||||
})),
|
||||
_ => Some(EntitySpawnPacket::SpawnEntity(AddEntity {
|
||||
_ => Some(EntitySpawnPacket::Entity(AddEntity {
|
||||
entity_id: VarInt(this_id.to_network_id()),
|
||||
object_uuid: self.uuid,
|
||||
kind: VarInt(self.kind() as i32),
|
||||
|
@ -588,17 +590,17 @@ pub(crate) fn velocity_to_packet_units(vel: Vec3<f32>) -> Vec3<i16> {
|
|||
}
|
||||
|
||||
pub(crate) enum EntitySpawnPacket {
|
||||
SpawnEntity(AddEntity),
|
||||
SpawnExperienceOrb(AddExperienceOrb),
|
||||
SpawnPlayer(AddPlayer),
|
||||
Entity(AddEntity),
|
||||
ExperienceOrb(AddExperienceOrb),
|
||||
Player(AddPlayer),
|
||||
}
|
||||
|
||||
impl From<EntitySpawnPacket> for S2cPlayPacket {
|
||||
fn from(pkt: EntitySpawnPacket) -> Self {
|
||||
match pkt {
|
||||
EntitySpawnPacket::SpawnEntity(pkt) => pkt.into(),
|
||||
EntitySpawnPacket::SpawnExperienceOrb(pkt) => pkt.into(),
|
||||
EntitySpawnPacket::SpawnPlayer(pkt) => pkt.into(),
|
||||
EntitySpawnPacket::Entity(pkt) => pkt.into(),
|
||||
EntitySpawnPacket::ExperienceOrb(pkt) => pkt.into(),
|
||||
EntitySpawnPacket::Player(pkt) => pkt.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
12
src/ident.rs
12
src/ident.rs
|
@ -1,3 +1,5 @@
|
|||
//! Namespaced identifiers.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::io::{Read, Write};
|
||||
use std::str::FromStr;
|
||||
|
@ -27,7 +29,9 @@ pub struct Ident {
|
|||
colon_idx: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Error, PartialEq, Eq, Debug)]
|
||||
/// The error type which is created when an [`Ident`] cannot be parsed from a
|
||||
/// string.
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("invalid identifier \"{src}\"")]
|
||||
pub struct ParseError {
|
||||
src: Cow<'static, str>,
|
||||
|
@ -36,8 +40,7 @@ pub struct ParseError {
|
|||
impl Ident {
|
||||
/// Parses a new identifier from a string.
|
||||
///
|
||||
/// The string must match the regex `([a-z0-9_-]+:)?[a-z0-9_\/.-]+`.
|
||||
/// If not, an error is returned.
|
||||
/// An error is returned if the string is not a valid identifier.
|
||||
pub fn new(str: impl Into<Cow<'static, str>>) -> Result<Ident, ParseError> {
|
||||
#![allow(bindings_with_variant_name)]
|
||||
|
||||
|
@ -106,7 +109,7 @@ impl Ident {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the identifier as a `str`.
|
||||
/// Returns the original string as a `str`.
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.ident.as_str()
|
||||
}
|
||||
|
@ -120,6 +123,7 @@ fn ascii_cow_to_str_cow(cow: Cow<AsciiStr>) -> Cow<str> {
|
|||
}
|
||||
|
||||
impl ParseError {
|
||||
/// Gets the string that caused the parse error.
|
||||
pub fn into_source(self) -> Cow<'static, str> {
|
||||
self.src
|
||||
}
|
||||
|
|
23
src/lib.rs
23
src/lib.rs
|
@ -1,4 +1,4 @@
|
|||
//! A Rust framework for building efficient Minecraft servers.
|
||||
//! 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
|
||||
|
@ -34,8 +34,8 @@
|
|||
//!
|
||||
//! **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 unspecified.
|
||||
//! These types should be considered pinned in memory.
|
||||
//! invariants within the library and the resulting behavior is safe but
|
||||
//! unspecified. These types should be considered [pinned](std::pin).
|
||||
//!
|
||||
//! Preventing this illegal behavior using Rust's type system was considered too
|
||||
//! cumbersome, so a note has been left here instead.
|
||||
|
@ -107,6 +107,11 @@
|
|||
unused_lifetimes,
|
||||
unused_import_braces
|
||||
)]
|
||||
#![allow(
|
||||
clippy::derive_partial_eq_without_eq,
|
||||
clippy::unusual_byte_groupings,
|
||||
clippy::comparison_chain
|
||||
)]
|
||||
|
||||
pub mod biome;
|
||||
pub mod block;
|
||||
|
@ -130,13 +135,21 @@ pub mod text;
|
|||
pub mod util;
|
||||
pub mod world;
|
||||
|
||||
/// Provides low-level access to the Minecraft protocol.
|
||||
#[cfg(feature = "protocol")]
|
||||
pub mod protocol {
|
||||
pub use crate::protocol_inner::*;
|
||||
}
|
||||
|
||||
/// Used on [`Config`](config::Config) to allow for async methods in traits.
|
||||
///
|
||||
/// For more information see the [async_trait] crate.
|
||||
///
|
||||
/// [async_trait]: https://docs.rs/async-trait/latest/async_trait/
|
||||
pub use async_trait::async_trait;
|
||||
#[doc(inline)]
|
||||
pub use server::start_server;
|
||||
#[doc(inline)]
|
||||
pub use {nbt, uuid, vek};
|
||||
|
||||
/// The Minecraft protocol version this library currently targets.
|
||||
|
@ -157,7 +170,3 @@ const LIBRARY_NAMESPACE: &str = "valence";
|
|||
/// The duration of a game update depends on the current configuration, which
|
||||
/// may or may not be the same as Minecraft's standard 20 ticks/second.
|
||||
pub type Ticks = i64;
|
||||
|
||||
/// Whatever dude
|
||||
#[cfg(feature = "whatever")]
|
||||
pub type Whatever = i64;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! The player list (tab list).
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
|
@ -297,6 +299,7 @@ impl PlayerListEntry {
|
|||
&self.username
|
||||
}
|
||||
|
||||
/// Gets the player textures for this entry.
|
||||
pub fn textures(&self) -> Option<&SignedPlayerTextures> {
|
||||
self.textures.as_ref()
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use url::Url;
|
|||
///
|
||||
/// This data has been cryptographically signed to ensure it will not be altered
|
||||
/// by the server.
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct SignedPlayerTextures {
|
||||
payload: Box<[u8]>,
|
||||
signature: Box<[u8]>,
|
||||
|
@ -57,7 +57,7 @@ impl SignedPlayerTextures {
|
|||
}
|
||||
|
||||
/// Contains URLs to the skin and cape of a player.
|
||||
#[derive(Clone, PartialEq, Default, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Default, Debug)]
|
||||
pub struct PlayerTextures {
|
||||
/// A URL to the skin of a player. Is `None` if the player does not have a
|
||||
/// skin.
|
||||
|
@ -82,7 +82,7 @@ struct PlayerTexturesPayload {
|
|||
cape: Option<TextureUrl>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
|
||||
struct TextureUrl {
|
||||
url: Url,
|
||||
}
|
||||
|
|
|
@ -269,6 +269,11 @@ impl Decode for Box<str> {
|
|||
}
|
||||
}
|
||||
|
||||
/// An integer with a minimum and maximum value known at compile time. `T` is
|
||||
/// the underlying integer type.
|
||||
///
|
||||
/// If the value is not in bounds, an error is generated while
|
||||
/// encoding or decoding.
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct BoundedInt<T, const MIN: i64, const MAX: i64>(pub T);
|
||||
|
||||
|
@ -320,8 +325,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: bounded float?
|
||||
|
||||
impl Encode for String {
|
||||
fn encode(&self, w: &mut impl Write) -> anyhow::Result<()> {
|
||||
encode_string_bounded(self, 0, 32767, w)
|
||||
|
@ -335,12 +338,11 @@ impl Decode for String {
|
|||
}
|
||||
|
||||
/// A string with a minimum and maximum character length known at compile time.
|
||||
///
|
||||
/// If the string is not in bounds, an error is generated while
|
||||
/// encoding/decoding.
|
||||
/// encoding or decoding.
|
||||
///
|
||||
/// Note that the length is a count of the characters in the string, not bytes.
|
||||
///
|
||||
/// When encoded and decoded, the string is VarInt prefixed.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash, Debug)]
|
||||
pub struct BoundedString<const MIN: usize, const MAX: usize>(pub String);
|
||||
|
||||
|
@ -462,10 +464,9 @@ impl<T: Decode> Decode for Vec4<T> {
|
|||
}
|
||||
|
||||
/// An array with a minimum and maximum character length known at compile time.
|
||||
/// If the array is not in bounds, an error is generated while
|
||||
/// encoding/decoding.
|
||||
///
|
||||
/// When encoding/decoding, the array is VarInt prefixed.
|
||||
/// If the array is not in bounds, an error is generated while
|
||||
/// encoding or decoding.
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash, Debug)]
|
||||
pub struct BoundedArray<T, const MIN: usize = 0, const MAX: usize = { usize::MAX }>(pub Vec<T>);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// Reading and writing whole packets.
|
||||
|
||||
use std::io::Read;
|
||||
use std::time::Duration;
|
||||
|
||||
|
@ -296,7 +298,7 @@ mod tests {
|
|||
|
||||
async fn send_test_packet(w: &mut Encoder<TcpStream>) {
|
||||
w.write_packet(&TestPacket {
|
||||
first: "abcdefghijklmnopqrstuvwxyz".to_string().into(),
|
||||
first: "abcdefghijklmnopqrstuvwxyz".into(),
|
||||
second: vec![0x1234, 0xabcd],
|
||||
third: 0x1122334455667788,
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Packet definitions and some types contained within them.
|
||||
//! Packet definitions and related types.
|
||||
//!
|
||||
//! See <https://wiki.vg/Protocol> for more packet documentation.
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! The heart of the server.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::iter::FusedIterator;
|
||||
|
@ -106,9 +108,14 @@ struct SharedServerInner {
|
|||
|
||||
/// Contains information about a new client.
|
||||
pub struct NewClientData {
|
||||
/// The UUID of the new client.
|
||||
pub uuid: Uuid,
|
||||
/// The username of the new client.
|
||||
pub username: String,
|
||||
/// The new client's player textures. May be `None` if the client does not
|
||||
/// have a skin or cape.
|
||||
pub textures: Option<SignedPlayerTextures>,
|
||||
/// The remote address of the new client.
|
||||
pub remote_addr: SocketAddr,
|
||||
}
|
||||
|
||||
|
@ -232,7 +239,7 @@ impl SharedServer {
|
|||
/// Consumes the configuration and starts the server.
|
||||
///
|
||||
/// The function returns once the server has shut down, a runtime error
|
||||
/// occurs, or the configuration is invalid.
|
||||
/// occurs, or the configuration is found to be invalid.
|
||||
pub fn start_server(config: impl Config) -> ShutdownResult {
|
||||
let shared = setup_server(config).map_err(Box::<dyn Error + Send + Sync + 'static>::from)?;
|
||||
|
||||
|
|
13
src/text.rs
13
src/text.rs
|
@ -1,3 +1,5 @@
|
|||
//! Formatted text.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::io::{Read, Write};
|
||||
|
@ -104,6 +106,7 @@ impl Text {
|
|||
/// convert the type into [`Text`]. A blanket implementation exists for all
|
||||
/// `Into<Text>` types, including [`Text`] itself.
|
||||
pub trait TextFormat: Into<Text> {
|
||||
/// Converts this type into a [`Text`] object.
|
||||
fn into_text(self) -> Text {
|
||||
self.into()
|
||||
}
|
||||
|
@ -305,10 +308,14 @@ enum TextContent {
|
|||
// TODO: nbt
|
||||
}
|
||||
|
||||
/// Text color
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct Color {
|
||||
/// Red channel
|
||||
pub r: u8,
|
||||
/// Green channel
|
||||
pub g: u8,
|
||||
/// Blue channel
|
||||
pub b: u8,
|
||||
}
|
||||
|
||||
|
@ -344,6 +351,7 @@ enum HoverEvent {
|
|||
|
||||
#[allow(clippy::self_named_constructors)]
|
||||
impl Text {
|
||||
/// Constructs a new plain text object.
|
||||
pub fn text(plain: impl Into<Cow<'static, str>>) -> Self {
|
||||
Self {
|
||||
content: TextContent::Text { text: plain.into() },
|
||||
|
@ -351,6 +359,7 @@ impl Text {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create translated text based on the given translation key.
|
||||
pub fn translate(key: impl Into<Cow<'static, str>>) -> Self {
|
||||
Self {
|
||||
content: TextContent::Translate {
|
||||
|
@ -360,6 +369,7 @@ impl Text {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets this text object as plain text without any formatting.
|
||||
pub fn to_plain(&self) -> String {
|
||||
let mut res = String::new();
|
||||
self.write_plain(&mut res)
|
||||
|
@ -367,6 +377,7 @@ impl Text {
|
|||
res
|
||||
}
|
||||
|
||||
/// Writes this text object as plain text to the provided writer.
|
||||
pub fn write_plain(&self, w: &mut impl fmt::Write) -> fmt::Result {
|
||||
match &self.content {
|
||||
TextContent::Text { text } => w.write_str(text.as_ref())?,
|
||||
|
@ -458,6 +469,7 @@ impl Default for TextContent {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
impl Color {
|
||||
pub const AQUA: Color = Color::new(85, 255, 255);
|
||||
pub const BLACK: Color = Color::new(0, 0, 0);
|
||||
|
@ -476,6 +488,7 @@ impl Color {
|
|||
pub const WHITE: Color = Color::new(255, 255, 255);
|
||||
pub const YELLOW: Color = Color::new(255, 255, 85);
|
||||
|
||||
/// Constructs a new color from red, green, and blue components.
|
||||
pub const fn new(r: u8, g: u8, b: u8) -> Self {
|
||||
Self { r, g, b }
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::chunk_pos::ChunkPos;
|
|||
/// assert!(valid_username("jeb_"));
|
||||
///
|
||||
/// assert!(!valid_username("notavalidusername"));
|
||||
/// assert!(!valid_username("NotValid!"))
|
||||
/// assert!(!valid_username("NotValid!"));
|
||||
/// ```
|
||||
pub fn valid_username(s: &str) -> bool {
|
||||
(3..=16).contains(&s.len())
|
||||
|
@ -44,6 +44,8 @@ pub fn chunks_in_view_distance(
|
|||
.filter(move |&p| is_chunk_in_view_distance(center, p, distance))
|
||||
}
|
||||
|
||||
/// Checks if two chunks are within a view distance of each other such that a
|
||||
/// client standing in one chunk would be able to see the other.
|
||||
pub fn is_chunk_in_view_distance(p0: ChunkPos, p1: ChunkPos, distance: u8) -> bool {
|
||||
(p0.x as f64 - p1.x as f64).powi(2) + (p0.z as f64 - p1.z as f64).powi(2)
|
||||
<= (distance as f64 + EXTRA_RADIUS as f64).powi(2)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! A space on a server for objects to occupy.
|
||||
|
||||
use std::iter::FusedIterator;
|
||||
|
||||
use rayon::iter::ParallelIterator;
|
||||
|
@ -9,12 +11,13 @@ use crate::server::SharedServer;
|
|||
use crate::slotmap::{Key, SlotMap};
|
||||
use crate::spatial_index::SpatialIndex;
|
||||
|
||||
/// A container for all [`World`]s on a [`Server`](crate::server::Server).
|
||||
pub struct Worlds {
|
||||
sm: SlotMap<World>,
|
||||
server: SharedServer,
|
||||
}
|
||||
|
||||
/// A key for a [`World`] on the server.
|
||||
/// An identifier for a [`World`] on the server.
|
||||
///
|
||||
/// World IDs are either _valid_ or _invalid_. Valid world IDs point to
|
||||
/// worlds that have not been deleted, while invalid IDs point to those that
|
||||
|
|
Loading…
Reference in a new issue