More clippy lints

Also made some vars NonZero
This commit is contained in:
Alexander Medvedev 2024-12-19 01:25:19 +01:00
parent 133ef45c19
commit cc0f30848e
31 changed files with 140 additions and 105 deletions

View File

@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets --all-features --no-default-features - run: cargo clippy --all-targets --all-features
build_and_test: build_and_test:
name: Build project and test name: Build project and test
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -77,4 +77,4 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- run: cargo clippy --release --all-targets --all-features --no-default-features - run: cargo clippy --release --all-targets --all-features

View File

@ -7,6 +7,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{ use std::{
fs, fs,
net::{Ipv4Addr, SocketAddr}, net::{Ipv4Addr, SocketAddr},
num::NonZeroU8,
path::Path, path::Path,
sync::LazyLock, sync::LazyLock,
}; };
@ -71,9 +72,9 @@ pub struct BasicConfiguration {
/// The maximum number of players allowed on the server. Specifying `0` disables the limit. /// The maximum number of players allowed on the server. Specifying `0` disables the limit.
pub max_players: u32, pub max_players: u32,
/// The maximum view distance for players. /// The maximum view distance for players.
pub view_distance: u8, pub view_distance: NonZeroU8,
/// The maximum simulated view distance. /// The maximum simulated view distance.
pub simulation_distance: u8, pub simulation_distance: NonZeroU8,
/// The default game difficulty. /// The default game difficulty.
pub default_difficulty: Difficulty, pub default_difficulty: Difficulty,
/// Whether the Nether dimension is enabled. /// Whether the Nether dimension is enabled.
@ -103,8 +104,8 @@ impl Default for BasicConfiguration {
server_address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 25565), server_address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 25565),
seed: "".to_string(), seed: "".to_string(),
max_players: 100000, max_players: 100000,
view_distance: 10, view_distance: NonZeroU8::new(10).unwrap(),
simulation_distance: 10, simulation_distance: NonZeroU8::new(10).unwrap(),
default_difficulty: Difficulty::Normal, default_difficulty: Difficulty::Normal,
allow_nether: true, allow_nether: true,
hardcore: false, hardcore: false,
@ -176,9 +177,14 @@ impl LoadConfiguration for BasicConfiguration {
} }
fn validate(&self) { fn validate(&self) {
assert!(self.view_distance >= 2, "View distance must be at least 2");
assert!( assert!(
self.view_distance <= 32, self.view_distance
.ge(unsafe { &NonZeroU8::new_unchecked(2) }),
"View distance must be at least 2"
);
assert!(
self.view_distance
.le(unsafe { &NonZeroU8::new_unchecked(32) }),
"View distance must be less than 32" "View distance must be less than 32"
); );
if self.online_mode { if self.online_mode {

View File

@ -1,3 +1,5 @@
use std::num::NonZeroU16;
use bytebuf::{packet_id::Packet, ReadingError}; use bytebuf::{packet_id::Packet, ReadingError};
use bytes::{Bytes, BytesMut}; use bytes::{Bytes, BytesMut};
use pumpkin_core::text::{style::Style, TextComponent}; use pumpkin_core::text::{style::Style, TextComponent};
@ -19,7 +21,7 @@ pub use var_long::*;
/// To current Minecraft protocol /// To current Minecraft protocol
/// Don't forget to change this when porting /// Don't forget to change this when porting
pub const CURRENT_MC_PROTOCOL: u32 = 769; pub const CURRENT_MC_PROTOCOL: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(769) };
pub const MAX_PACKET_SIZE: i32 = 2097152; pub const MAX_PACKET_SIZE: i32 = 2097152;

View File

@ -1,3 +1,5 @@
use std::num::NonZeroUsize;
use bytes::{Buf, BufMut}; use bytes::{Buf, BufMut};
use serde::{ use serde::{
de::{SeqAccess, Visitor}, de::{SeqAccess, Visitor},
@ -15,7 +17,7 @@ pub struct VarInt(pub VarIntType);
impl VarInt { impl VarInt {
/// The maximum number of bytes a `VarInt` can occupy. /// The maximum number of bytes a `VarInt` can occupy.
pub const MAX_SIZE: usize = 5; pub const MAX_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(5) };
/// Returns the exact number of bytes this varint will write when /// Returns the exact number of bytes this varint will write when
/// [`Encode::encode`] is called, assuming no error occurs. /// [`Encode::encode`] is called, assuming no error occurs.
@ -28,7 +30,7 @@ impl VarInt {
pub fn encode(&self, w: &mut impl BufMut) { pub fn encode(&self, w: &mut impl BufMut) {
let mut val = self.0; let mut val = self.0;
for _ in 0..Self::MAX_SIZE { for _ in 0..Self::MAX_SIZE.get() {
let b: u8 = val as u8 & 0b01111111; let b: u8 = val as u8 & 0b01111111;
val >>= 7; val >>= 7;
w.put_u8(if val == 0 { b } else { b | 0b10000000 }); w.put_u8(if val == 0 { b } else { b | 0b10000000 });
@ -40,7 +42,7 @@ impl VarInt {
pub fn decode(r: &mut impl Buf) -> Result<Self, VarIntDecodeError> { pub fn decode(r: &mut impl Buf) -> Result<Self, VarIntDecodeError> {
let mut val = 0; let mut val = 0;
for i in 0..Self::MAX_SIZE { for i in 0..Self::MAX_SIZE.get() {
if !r.has_remaining() { if !r.has_remaining() {
return Err(VarIntDecodeError::Incomplete); return Err(VarIntDecodeError::Incomplete);
} }
@ -130,7 +132,7 @@ impl<'de> Deserialize<'de> for VarInt {
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let mut val = 0; let mut val = 0;
for i in 0..VarInt::MAX_SIZE { for i in 0..VarInt::MAX_SIZE.get() {
if let Some(byte) = seq.next_element::<u8>()? { if let Some(byte) = seq.next_element::<u8>()? {
val |= (i32::from(byte) & 0b01111111) << (i * 7); val |= (i32::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 { if byte & 0b10000000 == 0 {

View File

@ -1,3 +1,5 @@
use std::num::NonZeroUsize;
use bytes::{Buf, BufMut}; use bytes::{Buf, BufMut};
use serde::{ use serde::{
de::{self, SeqAccess, Visitor}, de::{self, SeqAccess, Visitor},
@ -15,7 +17,7 @@ pub struct VarLong(pub VarLongType);
impl VarLong { impl VarLong {
/// The maximum number of bytes a `VarLong` /// The maximum number of bytes a `VarLong`
pub const MAX_SIZE: usize = 10; pub const MAX_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(10) };
/// Returns the exact number of bytes this varlong will write when /// Returns the exact number of bytes this varlong will write when
/// [`Encode::encode`] is called, assuming no error occurs. /// [`Encode::encode`] is called, assuming no error occurs.
@ -28,7 +30,7 @@ impl VarLong {
pub fn encode(&self, w: &mut impl BufMut) { pub fn encode(&self, w: &mut impl BufMut) {
let mut x = self.0; let mut x = self.0;
for _ in 0..Self::MAX_SIZE { for _ in 0..Self::MAX_SIZE.get() {
let byte = (x & 0x7F) as u8; let byte = (x & 0x7F) as u8;
x >>= 7; x >>= 7;
if x == 0 { if x == 0 {
@ -41,7 +43,7 @@ impl VarLong {
pub fn decode(r: &mut impl Buf) -> Result<Self, VarLongDecodeError> { pub fn decode(r: &mut impl Buf) -> Result<Self, VarLongDecodeError> {
let mut val = 0; let mut val = 0;
for i in 0..Self::MAX_SIZE { for i in 0..Self::MAX_SIZE.get() {
if !r.has_remaining() { if !r.has_remaining() {
return Err(VarLongDecodeError::Incomplete); return Err(VarLongDecodeError::Incomplete);
} }
@ -131,7 +133,7 @@ impl<'de> Deserialize<'de> for VarLong {
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let mut val = 0; let mut val = 0;
for i in 0..VarLong::MAX_SIZE { for i in 0..VarLong::MAX_SIZE.get() {
if let Some(byte) = seq.next_element::<u8>()? { if let Some(byte) = seq.next_element::<u8>()? {
val |= (i64::from(byte) & 0b01111111) << (i * 7); val |= (i64::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 { if byte & 0b10000000 == 0 {

View File

@ -1,13 +1,15 @@
use std::num::NonZeroU8;
use pumpkin_core::math::vector2::Vector2; use pumpkin_core::math::vector2::Vector2;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Cylindrical { pub struct Cylindrical {
pub center: Vector2<i32>, pub center: Vector2<i32>,
pub view_distance: u8, pub view_distance: NonZeroU8,
} }
impl Cylindrical { impl Cylindrical {
pub fn new(center: Vector2<i32>, view_distance: u8) -> Self { pub fn new(center: Vector2<i32>, view_distance: NonZeroU8) -> Self {
Self { Self {
center, center,
view_distance, view_distance,
@ -36,19 +38,19 @@ impl Cylindrical {
} }
fn left(&self) -> i32 { fn left(&self) -> i32 {
self.center.x - self.view_distance as i32 - 1 self.center.x - self.view_distance.get() as i32 - 1
} }
fn bottom(&self) -> i32 { fn bottom(&self) -> i32 {
self.center.z - self.view_distance as i32 - 1 self.center.z - self.view_distance.get() as i32 - 1
} }
fn right(&self) -> i32 { fn right(&self) -> i32 {
self.center.x + self.view_distance as i32 + 1 self.center.x + self.view_distance.get() as i32 + 1
} }
fn top(&self) -> i32 { fn top(&self) -> i32 {
self.center.z + self.view_distance as i32 + 1 self.center.z + self.view_distance.get() as i32 + 1
} }
fn is_within_distance(&self, x: i32, z: i32) -> bool { fn is_within_distance(&self, x: i32, z: i32) -> bool {
@ -59,7 +61,7 @@ impl Cylindrical {
let min_leg = rel_x.min(rel_z) as i64; let min_leg = rel_x.min(rel_z) as i64;
let hyp_sqr = max_leg * max_leg + min_leg * min_leg; let hyp_sqr = max_leg * max_leg + min_leg * min_leg;
hyp_sqr < (self.view_distance as i64 * self.view_distance as i64) hyp_sqr < (self.view_distance.get() as i64 * self.view_distance.get() as i64)
} }
/// Returns an iterator of all chunks within this cylinder /// Returns an iterator of all chunks within this cylinder
@ -82,12 +84,14 @@ impl Cylindrical {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::num::NonZeroU8;
use super::Cylindrical; use super::Cylindrical;
use pumpkin_core::math::vector2::Vector2; use pumpkin_core::math::vector2::Vector2;
#[test] #[test]
fn test_bounds() { fn test_bounds() {
let cylinder = Cylindrical::new(Vector2::new(0, 0), 10); let cylinder = Cylindrical::new(Vector2::new(0, 0), unsafe { NonZeroU8::new_unchecked(1) });
for chunk in cylinder.all_chunks_within() { for chunk in cylinder.all_chunks_within() {
assert!(chunk.x >= cylinder.left() && chunk.x <= cylinder.right()); assert!(chunk.x >= cylinder.left() && chunk.x <= cylinder.right());
assert!(chunk.z >= cylinder.bottom() && chunk.z <= cylinder.top()); assert!(chunk.z >= cylinder.bottom() && chunk.z <= cylinder.top());

View File

@ -21,8 +21,7 @@ pub struct BlockManager {
impl BlockManager { impl BlockManager {
pub fn register<T: PumpkinBlock + BlockMetadata + 'static>(&mut self, block: T) { pub fn register<T: PumpkinBlock + BlockMetadata + 'static>(&mut self, block: T) {
self.blocks self.blocks.insert(block.name(), Arc::new(block));
.insert(block.name().to_string(), Arc::new(block));
} }
pub async fn on_use( pub async fn on_use(

View File

@ -29,7 +29,10 @@ use pumpkin_protocol::{
}, },
ConnectionState, KnownPack, VarInt, CURRENT_MC_PROTOCOL, ConnectionState, KnownPack, VarInt, CURRENT_MC_PROTOCOL,
}; };
use std::sync::LazyLock; use std::{
num::{NonZeroI32, NonZeroU8},
sync::LazyLock,
};
use uuid::Uuid; use uuid::Uuid;
static LINKS: LazyLock<Vec<Link>> = LazyLock::new(|| { static LINKS: LazyLock<Vec<Link>> = LazyLock::new(|| {
@ -106,7 +109,7 @@ impl Client {
self.connection_state.store(handshake.next_state); self.connection_state.store(handshake.next_state);
if self.connection_state.load() != ConnectionState::Status { if self.connection_state.load() != ConnectionState::Status {
let protocol = version; let protocol = version;
match protocol.cmp(&(CURRENT_MC_PROTOCOL as i32)) { match protocol.cmp(&NonZeroI32::from(CURRENT_MC_PROTOCOL).get()) {
std::cmp::Ordering::Less => { std::cmp::Ordering::Less => {
self.kick(&format!("Client outdated ({protocol}), Server uses Minecraft {CURRENT_MC_VERSION}, Protocol {CURRENT_MC_PROTOCOL}")).await; self.kick(&format!("Client outdated ({protocol}), Server uses Minecraft {CURRENT_MC_VERSION}, Protocol {CURRENT_MC_PROTOCOL}")).await;
} }
@ -132,10 +135,7 @@ impl Client {
} }
fn is_valid_player_name(name: &str) -> bool { fn is_valid_player_name(name: &str) -> bool {
name.len() <= 16 name.len() <= 16 && name.chars().all(|c| c > 32u8 as char && c < 127u8 as char)
&& name
.chars()
.all(|c| c > 32_u8 as char && c < 127_u8 as char)
} }
pub async fn handle_login_start(&self, server: &Server, login_start: SLoginStart) { pub async fn handle_login_start(&self, server: &Server, login_start: SLoginStart) {
@ -400,7 +400,9 @@ impl Client {
) { ) {
*self.config.lock().await = Some(PlayerConfig { *self.config.lock().await = Some(PlayerConfig {
locale: client_information.locale, locale: client_information.locale,
view_distance: client_information.view_distance as u8, view_distance: unsafe {
NonZeroU8::new_unchecked(client_information.view_distance as u8)
},
chat_mode, chat_mode,
chat_colors: client_information.chat_colors, chat_colors: client_information.chat_colors,
skin_parts: client_information.skin_parts, skin_parts: client_information.skin_parts,

View File

@ -1,6 +1,7 @@
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
net::SocketAddr, net::SocketAddr,
num::NonZeroU8,
sync::{ sync::{
atomic::{AtomicBool, AtomicI32}, atomic::{AtomicBool, AtomicI32},
Arc, Arc,
@ -53,7 +54,7 @@ pub struct PlayerConfig {
/// The player's preferred language. /// The player's preferred language.
pub locale: String, // 16 pub locale: String, // 16
/// The maximum distance at which chunks are rendered. /// The maximum distance at which chunks are rendered.
pub view_distance: u8, pub view_distance: NonZeroU8,
/// The player's chat mode settings /// The player's chat mode settings
pub chat_mode: ChatMode, pub chat_mode: ChatMode,
/// Whether chat colors are enabled. /// Whether chat colors are enabled.
@ -72,7 +73,7 @@ impl Default for PlayerConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
locale: "en_us".to_string(), locale: "en_us".to_string(),
view_distance: 2, view_distance: unsafe { NonZeroU8::new_unchecked(10) },
chat_mode: ChatMode::Enabled, chat_mode: ChatMode::Enabled,
chat_colors: true, chat_colors: true,
skin_parts: 0, skin_parts: 0,

View File

@ -1,3 +1,4 @@
use std::num::NonZeroU8;
use std::sync::Arc; use std::sync::Arc;
use super::PlayerConfig; use super::PlayerConfig;
@ -436,7 +437,7 @@ impl Player {
} }
pub async fn handle_client_information( pub async fn handle_client_information(
self: &Arc<Player>, self: &Arc<Self>,
client_information: SClientInformationPlay, client_information: SClientInformationPlay,
) { ) {
if let (Some(main_hand), Some(chat_mode)) = ( if let (Some(main_hand), Some(chat_mode)) = (
@ -458,25 +459,27 @@ impl Player {
let old_view_distance = config.view_distance; let old_view_distance = config.view_distance;
let update_watched = if old_view_distance == client_information.view_distance as u8 let update_watched =
{ if old_view_distance.get() == client_information.view_distance as u8 {
false false
} else { } else {
log::debug!( log::debug!(
"Player {} ({}) updated render distance: {} -> {}.", "Player {} ({}) updated render distance: {} -> {}.",
self.gameprofile.name, self.gameprofile.name,
self.client.id, self.client.id,
old_view_distance, old_view_distance,
client_information.view_distance client_information.view_distance
); );
true true
}; };
*config = PlayerConfig { *config = PlayerConfig {
locale: client_information.locale, locale: client_information.locale,
// A Negative view distance would be impossible and make no sense right ?, Mojang: Lets make is signed :D // A Negative view distance would be impossible and make no sense right ?, Mojang: Lets make is signed :D
view_distance: client_information.view_distance as u8, view_distance: unsafe {
NonZeroU8::new_unchecked(client_information.view_distance as u8)
},
chat_mode, chat_mode,
chat_colors: client_information.chat_colors, chat_colors: client_information.chat_colors,
skin_parts: client_information.skin_parts, skin_parts: client_information.skin_parts,

View File

@ -65,12 +65,14 @@ impl<'a> FindArg<'a> for BlockArgumentConsumer {
fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result<Self::Data, CommandError> { fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result<Self::Data, CommandError> {
match args.get(name) { match args.get(name) {
Some(Arg::Block(name)) => match block_registry::get_block(name) { Some(Arg::Block(name)) => block_registry::get_block(name).map_or_else(
Some(block) => Ok(block), || {
None => Err(CommandError::GeneralCommandIssue(format!( Err(CommandError::GeneralCommandIssue(format!(
"Block {name} does not exist." "Block {name} does not exist."
))), )))
}, },
Result::Ok,
),
_ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))),
} }
} }

View File

@ -22,7 +22,7 @@ pub(crate) struct BoundedNumArgumentConsumer<T: ToFromNumber> {
#[async_trait] #[async_trait]
impl<T: ToFromNumber> ArgumentConsumer for BoundedNumArgumentConsumer<T> impl<T: ToFromNumber> ArgumentConsumer for BoundedNumArgumentConsumer<T>
where where
BoundedNumArgumentConsumer<T>: GetClientSideArgParser, Self: GetClientSideArgParser,
{ {
async fn consume<'a>( async fn consume<'a>(
&self, &self,
@ -236,7 +236,7 @@ impl GetClientSideArgParser for BoundedNumArgumentConsumer<i64> {
impl<T: ToFromNumber> DefaultNameArgConsumer for BoundedNumArgumentConsumer<T> impl<T: ToFromNumber> DefaultNameArgConsumer for BoundedNumArgumentConsumer<T>
where where
BoundedNumArgumentConsumer<T>: ArgumentConsumer, Self: ArgumentConsumer,
{ {
fn default_name(&self) -> &'static str { fn default_name(&self) -> &'static str {
// setting a single default name for all BoundedNumArgumentConsumer variants is probably a bad idea since it would lead to confusion // setting a single default name for all BoundedNumArgumentConsumer variants is probably a bad idea since it would lead to confusion

View File

@ -38,10 +38,9 @@ impl ArgumentConsumer for CommandTreeArgumentConsumer {
let s = args.pop()?; let s = args.pop()?;
let dispatcher = &server.command_dispatcher; let dispatcher = &server.command_dispatcher;
return match dispatcher.get_tree(s) { return dispatcher
Ok(tree) => Some(Arg::CommandTree(tree)), .get_tree(s)
Err(_) => None, .map_or_else(|_| None, |tree| Some(Arg::CommandTree(tree)));
};
} }
async fn suggest<'a>( async fn suggest<'a>(
@ -71,7 +70,7 @@ impl DefaultNameArgConsumer for CommandTreeArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&CommandTreeArgumentConsumer &Self
} }
} }

View File

@ -62,7 +62,7 @@ impl DefaultNameArgConsumer for EntitiesArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&EntitiesArgumentConsumer &Self
} }
} }

View File

@ -84,7 +84,7 @@ impl DefaultNameArgConsumer for EntityArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&EntityArgumentConsumer &Self
} }
} }

View File

@ -65,7 +65,7 @@ impl DefaultNameArgConsumer for GamemodeArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&GamemodeArgumentConsumer &Self
} }
} }

View File

@ -63,12 +63,14 @@ impl<'a> FindArg<'a> for ItemArgumentConsumer {
fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result<Self::Data, CommandError> { fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result<Self::Data, CommandError> {
match args.get(name) { match args.get(name) {
Some(Arg::Item(name)) => match item_registry::get_item(name) { Some(Arg::Item(name)) => item_registry::get_item(name).map_or_else(
Some(item) => Ok((name, item)), || {
None => Err(CommandError::GeneralCommandIssue(format!( Err(CommandError::GeneralCommandIssue(format!(
"Item {name} does not exist." "Item {name} does not exist."
))), )))
}, },
|item| Ok((*name, item)),
),
_ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))),
} }
} }

View File

@ -60,7 +60,7 @@ impl DefaultNameArgConsumer for MsgArgConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&MsgArgConsumer &Self
} }
} }

View File

@ -53,11 +53,7 @@ impl ArgumentConsumer for PlayersArgumentConsumer {
_ => None, _ => None,
}, },
"@r" => { "@r" => {
if let Some(p) = server.get_random_player().await { (server.get_random_player().await).map_or_else(|| Some(vec![]), |p| Some(vec![p]))
Some(vec![p.clone()])
} else {
Some(vec![])
}
} }
"@a" | "@e" => Some(server.get_all_players().await), "@a" | "@e" => Some(server.get_all_players().await),
name => server.get_player_by_name(name).await.map(|p| vec![p]), name => server.get_player_by_name(name).await.map(|p| vec![p]),
@ -82,7 +78,7 @@ impl DefaultNameArgConsumer for PlayersArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&PlayersArgumentConsumer &Self
} }
} }

View File

@ -78,7 +78,7 @@ impl DefaultNameArgConsumer for Position2DArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&Position2DArgumentConsumer &Self
} }
} }

View File

@ -81,7 +81,7 @@ impl DefaultNameArgConsumer for Position3DArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&Position3DArgumentConsumer &Self
} }
} }

View File

@ -82,7 +82,7 @@ impl DefaultNameArgConsumer for BlockPosArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&BlockPosArgumentConsumer &Self
} }
} }

View File

@ -66,7 +66,7 @@ impl DefaultNameArgConsumer for RotationArgumentConsumer {
} }
fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { fn get_argument_consumer(&self) -> &dyn ArgumentConsumer {
&RotationArgumentConsumer &Self
} }
} }

View File

@ -32,11 +32,11 @@ impl CommandError {
pub fn into_string_or_pumpkin_error(self, cmd: &str) -> Result<String, Box<dyn PumpkinError>> { pub fn into_string_or_pumpkin_error(self, cmd: &str) -> Result<String, Box<dyn PumpkinError>> {
match self { match self {
InvalidConsumption(s) => { InvalidConsumption(s) => {
println!("Error while parsing command \"{cmd}\": {s:?} was consumed, but couldn't be parsed"); log::error!("Error while parsing command \"{cmd}\": {s:?} was consumed, but couldn't be parsed");
Ok("Internal Error (See logs for details)".into()) Ok("Internal Error (See logs for details)".into())
} }
InvalidRequirement => { InvalidRequirement => {
println!("Error while parsing command \"{cmd}\": a requirement that was expected was not met."); log::error!("Error while parsing command \"{cmd}\": a requirement that was expected was not met.");
Ok("Internal Error (See logs for details)".into()) Ok("Internal Error (See logs for details)".into())
} }
GeneralCommandIssue(s) => Ok(s), GeneralCommandIssue(s) => Ok(s),

View File

@ -1,4 +1,5 @@
use std::{ use std::{
num::NonZeroU8,
sync::{ sync::{
atomic::{AtomicBool, AtomicI32, AtomicI64, AtomicU32, AtomicU8}, atomic::{AtomicBool, AtomicI32, AtomicI64, AtomicU32, AtomicU8},
Arc, Arc,
@ -176,7 +177,7 @@ impl Player {
// (We left shift by one so we can search around that chunk) // (We left shift by one so we can search around that chunk)
watched_section: AtomicCell::new(Cylindrical::new( watched_section: AtomicCell::new(Cylindrical::new(
Vector2::new(i32::MAX >> 1, i32::MAX >> 1), Vector2::new(i32::MAX >> 1, i32::MAX >> 1),
0, unsafe { NonZeroU8::new_unchecked(1) },
)), )),
wait_for_keep_alive: AtomicBool::new(false), wait_for_keep_alive: AtomicBool::new(false),
keep_alive_id: AtomicI64::new(0), keep_alive_id: AtomicI64::new(0),

View File

@ -2,7 +2,22 @@
#![deny(clippy::pedantic)] #![deny(clippy::pedantic)]
// #![warn(clippy::restriction)] // #![warn(clippy::restriction)]
#![deny(clippy::cargo)] #![deny(clippy::cargo)]
// to keep consistency
#![deny(clippy::if_then_some_else_none)] #![deny(clippy::if_then_some_else_none)]
#![deny(clippy::empty_enum_variants_with_brackets)]
#![deny(clippy::empty_structs_with_brackets)]
#![deny(clippy::separated_literal_suffix)]
#![deny(clippy::semicolon_outside_block)]
#![deny(clippy::non_zero_suggestions)]
#![deny(clippy::string_lit_chars_any)]
#![deny(clippy::use_self)]
#![deny(clippy::useless_let_if_seq)]
#![deny(clippy::branches_sharing_code)]
#![deny(clippy::equatable_if_let)]
#![deny(clippy::option_if_let_else)]
// use log crate
#![deny(clippy::print_stdout)]
#![deny(clippy::print_stderr)]
// REMOVE SOME WHEN RELEASE // REMOVE SOME WHEN RELEASE
#![expect(clippy::cargo_common_metadata)] #![expect(clippy::cargo_common_metadata)]
#![expect(clippy::multiple_crate_versions)] #![expect(clippy::multiple_crate_versions)]
@ -182,8 +197,8 @@ async fn main() {
let server = server.clone(); let server = server.clone();
tokio::spawn(async move { tokio::spawn(async move {
ticker.run(&server).await; ticker.run(&server).await;
}); })
} };
let mut master_client_id: u16 = 0; let mut master_client_id: u16 = 0;
loop { loop {

View File

@ -2,6 +2,7 @@ use core::error;
use std::{ use std::{
fs::File, fs::File,
io::{Cursor, Read}, io::{Cursor, Read},
num::NonZeroU32,
path::Path, path::Path,
}; };
@ -105,7 +106,7 @@ impl CachedStatus {
} }
pub fn build_response(config: &BasicConfiguration) -> StatusResponse { pub fn build_response(config: &BasicConfiguration) -> StatusResponse {
let icon = if config.use_favicon { let favicon = if config.use_favicon {
let icon_path = &config.favicon_path; let icon_path = &config.favicon_path;
log::debug!("Loading server favicon from '{}'", icon_path); log::debug!("Loading server favicon from '{}'", icon_path);
match load_icon_from_file(icon_path).or_else(|err| { match load_icon_from_file(icon_path).or_else(|err| {
@ -142,7 +143,7 @@ impl CachedStatus {
StatusResponse { StatusResponse {
version: Some(Version { version: Some(Version {
name: CURRENT_MC_VERSION.into(), name: CURRENT_MC_VERSION.into(),
protocol: CURRENT_MC_PROTOCOL, protocol: NonZeroU32::from(CURRENT_MC_PROTOCOL).get(),
}), }),
players: Some(Players { players: Some(Players {
max: config.max_players, max: config.max_players,
@ -150,7 +151,7 @@ impl CachedStatus {
sample: vec![], sample: vec![],
}), }),
description: config.motd.clone(), description: config.motd.clone(),
favicon: icon, favicon,
enforce_secure_chat: false, enforce_secure_chat: false,
} }
} }

View File

@ -43,7 +43,7 @@ pub struct Bossbar {
impl Bossbar { impl Bossbar {
#[must_use] #[must_use]
pub fn new(title: String) -> Bossbar { pub fn new(title: String) -> Self {
let uuid = Uuid::new_v4(); let uuid = Uuid::new_v4();
Self { Self {

View File

@ -53,7 +53,7 @@ impl Default for CustomBossbars {
impl CustomBossbars { impl CustomBossbars {
#[must_use] #[must_use]
pub fn new() -> CustomBossbars { pub fn new() -> Self {
Self { Self {
custom_bossbars: HashMap::new(), custom_bossbars: HashMap::new(),
} }

View File

@ -242,8 +242,8 @@ impl World {
base_config.hardcore, base_config.hardcore,
&dimensions, &dimensions,
base_config.max_players.into(), base_config.max_players.into(),
base_config.view_distance.into(), // TODO: view distance base_config.view_distance.get().into(), // TODO: view distance
base_config.simulation_distance.into(), // TODO: sim view dinstance base_config.simulation_distance.get().into(), // TODO: sim view dinstance
false, false,
true, true,
false, false,
@ -324,7 +324,7 @@ impl World {
.client .client
.send_packet(&CPlayerInfoUpdate::new(0x01 | 0x08, &entries)) .send_packet(&CPlayerInfoUpdate::new(0x01 | 0x08, &entries))
.await; .await;
} };
let gameprofile = &player.gameprofile; let gameprofile = &player.gameprofile;

View File

@ -1,4 +1,4 @@
use std::sync::Arc; use std::{num::NonZeroU8, sync::Arc};
use pumpkin_config::BASIC_CONFIG; use pumpkin_config::BASIC_CONFIG;
use pumpkin_core::{ use pumpkin_core::{
@ -10,13 +10,11 @@ use pumpkin_world::cylindrical_chunk_iterator::Cylindrical;
use crate::entity::player::Player; use crate::entity::player::Player;
pub async fn get_view_distance(player: &Player) -> u8 { pub async fn get_view_distance(player: &Player) -> NonZeroU8 {
player player.config.lock().await.view_distance.clamp(
.config unsafe { NonZeroU8::new_unchecked(2) },
.lock() BASIC_CONFIG.view_distance,
.await )
.view_distance
.clamp(2, BASIC_CONFIG.view_distance)
} }
pub async fn player_join(player: &Arc<Player>) { pub async fn player_join(player: &Arc<Player>) {