diff --git a/pumpkin-protocol/Cargo.toml b/pumpkin-protocol/Cargo.toml index f5256305b..abb54fc80 100644 --- a/pumpkin-protocol/Cargo.toml +++ b/pumpkin-protocol/Cargo.toml @@ -18,7 +18,7 @@ log.workspace = true num-traits.workspace = true num-derive.workspace = true -bytes = "1.7" +bytes = "1.8" flate2 = "1.0" diff --git a/pumpkin/Cargo.toml b/pumpkin/Cargo.toml index 878ce0c69..bbc747a44 100644 --- a/pumpkin/Cargo.toml +++ b/pumpkin/Cargo.toml @@ -30,7 +30,7 @@ num-derive.workspace = true serde.workspace = true serde_json = "1.0" -bytes = "1.7" +bytes = "1.8" rand = "0.8.5" diff --git a/pumpkin/src/entity/mod.rs b/pumpkin/src/entity/mod.rs index ad1b639b2..c3f294d01 100644 --- a/pumpkin/src/entity/mod.rs +++ b/pumpkin/src/entity/mod.rs @@ -90,22 +90,28 @@ impl Entity { /// Updates the entity's position, block position, and chunk position. /// /// This function calculates the new position, block position, and chunk position based on the provided coordinates. If any of these values change, the corresponding fields are updated. + #[expect(clippy::float_cmp)] pub fn set_pos(&self, x: f64, y: f64, z: f64) { let pos = self.pos.load(); if pos.x != x || pos.y != y || pos.z != z { self.pos.store(Vector3::new(x, y, z)); - let i = x.floor() as i32; - let j = y.floor() as i32; - let k = z.floor() as i32; + let floor_x = x.floor() as i32; + let floor_y = y.floor() as i32; + let floor_z = z.floor() as i32; let block_pos = self.block_pos.load(); let block_pos_vec = block_pos.0; - if i != block_pos_vec.x || j != block_pos_vec.y || k != block_pos_vec.z { - let new_block_pos = Vector3::new(i, j, k); + if floor_x != block_pos_vec.x + || floor_y != block_pos_vec.y + || floor_z != block_pos_vec.z + { + let new_block_pos = Vector3::new(floor_x, floor_y, floor_z); self.block_pos.store(WorldPosition(new_block_pos)); let chunk_pos = self.chunk_pos.load(); - if get_section_cord(i) != chunk_pos.x || get_section_cord(k) != chunk_pos.z { + if get_section_cord(floor_x) != chunk_pos.x + || get_section_cord(floor_z) != chunk_pos.z + { self.chunk_pos.store(Vector2::new( get_section_cord(new_block_pos.x), get_section_cord(new_block_pos.z), diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 293bc4cfe..09bb81f64 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -368,6 +368,7 @@ impl Player { } } + #[expect(clippy::too_many_lines)] pub async fn handle_play_packet( self: &Arc, server: &Arc, diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index 4b17ef4ea..5aece5ac0 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -1,25 +1,20 @@ #![deny(clippy::all)] -#![warn(clippy::pedantic)] +#![deny(clippy::pedantic)] // #![warn(clippy::restriction)] -#![warn(clippy::cargo)] +#![deny(clippy::cargo)] // REMOVE SOME WHEN RELEASE #![expect(clippy::cargo_common_metadata)] #![expect(clippy::multiple_crate_versions)] -#![expect(clippy::while_float)] #![expect(clippy::significant_drop_in_scrutinee)] #![expect(clippy::significant_drop_tightening)] -#![expect(clippy::future_not_send)] #![expect(clippy::single_call_fn)] #![expect(clippy::cast_sign_loss)] #![expect(clippy::cast_possible_truncation)] #![expect(clippy::cast_possible_wrap)] -#![expect(clippy::too_many_lines)] #![expect(clippy::missing_panics_doc)] #![expect(clippy::missing_errors_doc)] #![expect(clippy::module_name_repetitions)] #![expect(clippy::struct_excessive_bools)] -#![expect(clippy::many_single_char_names)] -#![expect(clippy::float_cmp)] #[cfg(target_os = "wasi")] compile_error!("Compiling for WASI targets is not supported!"); @@ -31,6 +26,13 @@ use server::{ticker::Ticker, Server}; use std::io::{self}; use tokio::io::{AsyncBufReadExt, BufReader}; +use std::sync::Arc; + +use pumpkin_config::{ADVANCED_CONFIG, BASIC_CONFIG}; +use pumpkin_core::text::{color::NamedColor, TextComponent}; +use rcon::RCONServer; +use std::time::Instant; + // Setup some tokens to allow us to identify which event is for which socket. pub mod client; @@ -87,20 +89,11 @@ const fn convert_logger_filter(level: pumpkin_config::logging::LevelFilter) -> L #[tokio::main] async fn main() -> io::Result<()> { - use std::sync::Arc; - - use pumpkin_config::{ADVANCED_CONFIG, BASIC_CONFIG}; - use pumpkin_core::text::{color::NamedColor, TextComponent}; - use rcon::RCONServer; - use std::time::Instant; - init_logger(); - // let rt = tokio::runtime::Builder::new_multi_thread() // .enable_all() // .build() // .unwrap(); - ctrlc::set_handler(|| { log::warn!( "{}", @@ -138,26 +131,7 @@ async fn main() -> io::Result<()> { log::info!("You now can connect to the server, Listening on {}", addr); if use_console { - let server = server.clone(); - tokio::spawn(async move { - let stdin = tokio::io::stdin(); - let mut reader = BufReader::new(stdin); - loop { - let mut out = String::new(); - - reader - .read_line(&mut out) - .await - .expect("Failed to read console line"); - - if !out.is_empty() { - let dispatcher = server.command_dispatcher.clone(); - dispatcher - .handle_command(&mut commands::CommandSender::Console, &server, &out) - .await; - } - } - }); + setup_console(server.clone()); } if rcon.enabled { let server = server.clone(); @@ -171,6 +145,7 @@ async fn main() -> io::Result<()> { ticker.run(&server).await; }); } + loop { // Asynchronously wait for an inbound socket. let (connection, address) = listener.accept().await?; @@ -208,7 +183,7 @@ async fn main() -> io::Result<()> { while !player .client .closed - .load(std::sync::atomic::Ordering::Relaxed) + .load(core::sync::atomic::Ordering::Relaxed) { let open = player.client.poll().await; if open { @@ -221,3 +196,25 @@ async fn main() -> io::Result<()> { }); } } + +fn setup_console(server: Arc) { + tokio::spawn(async move { + let stdin = tokio::io::stdin(); + let mut reader = BufReader::new(stdin); + loop { + let mut out = String::new(); + + reader + .read_line(&mut out) + .await + .expect("Failed to read console line"); + + if !out.is_empty() { + let dispatcher = server.command_dispatcher.clone(); + dispatcher + .handle_command(&mut commands::CommandSender::Console, &server, &out) + .await; + } + } + }); +} diff --git a/pumpkin/src/rcon/mod.rs b/pumpkin/src/rcon/mod.rs index b7b41352a..93ad9b511 100644 --- a/pumpkin/src/rcon/mod.rs +++ b/pumpkin/src/rcon/mod.rs @@ -1,7 +1,4 @@ -use std::{ - io::{self}, - net::SocketAddr, -}; +use std::net::SocketAddr; use packet::{ClientboundPacket, Packet, PacketError, ServerboundPacket}; use pumpkin_config::{RCONConfig, ADVANCED_CONFIG}; @@ -20,13 +17,13 @@ pub enum RCONError { #[error("command exceeds the maximum length")] CommandTooLong, #[error("{}", _0)] - Io(io::Error), + Io(std::io::Error), } pub struct RCONServer; impl RCONServer { - pub async fn new(config: &RCONConfig, server: Arc) -> Result { + pub async fn new(config: &RCONConfig, server: Arc) -> Result { assert!(config.enabled, "RCON is not enabled"); let listener = tokio::net::TcpListener::bind(config.address).await.unwrap(); @@ -141,7 +138,7 @@ impl RCONClient { Ok(()) } - async fn read_bytes(&mut self) -> io::Result { + async fn read_bytes(&mut self) -> std::io::Result { let mut buf = [0; 1460]; let n = self.connection.read(&mut buf).await?; if n == 0 { diff --git a/pumpkin/src/server/connection_cache.rs b/pumpkin/src/server/connection_cache.rs index 49eeff040..5f9cb4c30 100644 --- a/pumpkin/src/server/connection_cache.rs +++ b/pumpkin/src/server/connection_cache.rs @@ -3,7 +3,6 @@ use std::{ fs::File, io::{Cursor, Read}, path::Path, - sync::LazyLock, }; use base64::{engine::general_purpose, Engine as _}; @@ -15,8 +14,7 @@ use pumpkin_protocol::{ use super::CURRENT_MC_VERSION; -static DEFAULT_ICON: LazyLock<&[u8]> = - LazyLock::new(|| include_bytes!("../../../assets/default_icon.png")); +const DEFAULT_ICON: &[u8] = include_bytes!("../../../assets/default_icon.png"); fn load_icon_from_file>(path: P) -> Result> { let mut icon_file = File::open(path)?; @@ -112,7 +110,7 @@ impl CachedStatus { log::info!("Loading server favicon from '{}'", icon_path); match load_icon_from_file(icon_path).or_else(|err| { log::warn!("Failed to load icon from '{}': {}", icon_path, err); - load_icon_from_bytes(DEFAULT_ICON.as_ref()) + load_icon_from_bytes(DEFAULT_ICON) }) { Ok(result) => Some(result), Err(err) => { diff --git a/pumpkin/src/server/key_store.rs b/pumpkin/src/server/key_store.rs index becedf55d..81ad69cb2 100644 --- a/pumpkin/src/server/key_store.rs +++ b/pumpkin/src/server/key_store.rs @@ -1,14 +1,13 @@ use num_bigint::BigInt; use pumpkin_protocol::client::login::CEncryptionRequest; use rand::rngs::OsRng; -use rsa::{traits::PublicKeyParts as _, Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey}; +use rsa::{traits::PublicKeyParts as _, Pkcs1v15Encrypt, RsaPrivateKey}; use sha1::Sha1; use sha2::Digest; use crate::client::EncryptionError; pub struct KeyStore { - pub _public_key: RsaPublicKey, pub private_key: RsaPrivateKey, pub public_key_der: Box<[u8]>, } @@ -16,7 +15,7 @@ pub struct KeyStore { impl KeyStore { pub fn new() -> Self { log::debug!("Creating encryption keys..."); - let (public_key, private_key) = Self::generate_keys(); + let private_key = Self::generate_private_key(); let public_key_der = rsa_der::public_key_to_der( &private_key.n().to_bytes_be(), @@ -24,19 +23,17 @@ impl KeyStore { ) .into_boxed_slice(); Self { - _public_key: public_key, private_key, public_key_der, } } - fn generate_keys() -> (RsaPublicKey, RsaPrivateKey) { + fn generate_private_key() -> RsaPrivateKey { // Found out that OsRng is faster than rand::thread_rng here let mut rng = OsRng; - let priv_key = RsaPrivateKey::new(&mut rng, 1024).expect("failed to generate a key"); - let pub_key = RsaPublicKey::from(&priv_key); - (pub_key, priv_key) + // let pub_key = RsaPublicKey::from(&priv_key); + RsaPrivateKey::new(&mut rng, 1024).expect("failed to generate a key") } pub fn encryption_request<'a>( diff --git a/pumpkin/src/server/mod.rs b/pumpkin/src/server/mod.rs index e2a36afa0..810fab4c5 100644 --- a/pumpkin/src/server/mod.rs +++ b/pumpkin/src/server/mod.rs @@ -72,7 +72,6 @@ impl Server { // First register default command, after that plugins can put in their own let command_dispatcher = default_dispatcher(); - log::info!("Loading Plugins"); let world = World::load(Dimension::OverWorld.into_level( // TODO: load form config diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index e971910b0..4cccac5d5 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -118,6 +118,7 @@ impl World { } } + #[expect(clippy::too_many_lines)] pub async fn spawn_player(&self, base_config: &BasicConfiguration, player: Arc) { // This code follows the vanilla packet order let entity_id = player.entity_id();