From c6043189d3ab6803a34b1de389c954898f189e58 Mon Sep 17 00:00:00 2001 From: Asurar0 Date: Wed, 11 Sep 2024 22:39:53 +0200 Subject: [PATCH 1/3] Improved synchronization primitives - Replaced all `std::sync::Mutex` by `parking_lot::Mutex` and refactored implementation accordingly - Replaced all `Mutex where T: Copy` by `crossbeam::AtomicCell` and refactored implementation accordingly --- Cargo.lock | 84 +++++++++++++++++++++++++ Cargo.toml | 5 ++ pumpkin-core/src/math/position.rs | 1 + pumpkin-core/src/math/vector3.rs | 4 ++ pumpkin-inventory/Cargo.toml | 4 +- pumpkin-inventory/src/drag_handler.rs | 21 +++---- pumpkin-inventory/src/lib.rs | 1 + pumpkin-inventory/src/open_container.rs | 3 +- pumpkin-inventory/src/player.rs | 1 + pumpkin-protocol/src/lib.rs | 2 +- pumpkin-world/Cargo.toml | 2 + pumpkin-world/src/level.rs | 63 ++++++++++--------- pumpkin/Cargo.toml | 2 + pumpkin/src/client/client_packet.rs | 21 +++---- pumpkin/src/client/container.rs | 78 ++++++++++++----------- pumpkin/src/client/mod.rs | 34 +++++----- pumpkin/src/client/player_packet.rs | 70 ++++++++++----------- pumpkin/src/commands/cmd_echest.rs | 5 +- pumpkin/src/commands/cmd_gamemode.rs | 4 +- pumpkin/src/entity/mod.rs | 61 +++++++++--------- pumpkin/src/entity/player.rs | 56 +++++++++-------- pumpkin/src/main.rs | 4 +- pumpkin/src/proxy/velocity.rs | 2 +- pumpkin/src/server/mod.rs | 8 +-- pumpkin/src/world/mod.rs | 27 ++++---- pumpkin/src/world/player_chunker.rs | 19 +++--- 26 files changed, 338 insertions(+), 244 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c1cbac2c..fff734d23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -534,6 +534,28 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -553,6 +575,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -1409,6 +1440,16 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.22" @@ -1671,6 +1712,29 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + [[package]] name = "paste" version = "1.0.15" @@ -1858,6 +1922,7 @@ version = "0.1.0-dev" dependencies = [ "base64 0.22.1", "bytes", + "crossbeam", "ctrlc", "digest 0.11.0-pre.9", "hmac", @@ -1868,6 +1933,7 @@ dependencies = [ "num-bigint", "num-derive", "num-traits", + "parking_lot", "pumpkin-config", "pumpkin-core", "pumpkin-entity", @@ -1922,9 +1988,11 @@ version = "0.1.0" name = "pumpkin-inventory" version = "0.1.0" dependencies = [ + "crossbeam", "itertools 0.13.0", "num-derive", "num-traits", + "parking_lot", "pumpkin-world", "thiserror", ] @@ -1991,6 +2059,7 @@ dependencies = [ "noise", "num-derive", "num-traits", + "parking_lot", "pumpkin-core", "rand", "rayon", @@ -2117,6 +2186,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" version = "0.4.6" @@ -2376,6 +2454,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "semver" version = "1.0.23" diff --git a/Cargo.toml b/Cargo.toml index 38d79ccf3..9b13bf54b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,12 @@ tokio = { version = "1.40", features = [ "io-util", "sync", ] } + +# Concurrency/Parallelism and Synchronization rayon = "1.10.0" +parking_lot = "0.12.3" +crossbeam = "0.8.4" + uuid = { version = "1.10.0", features = ["serde", "v3", "v4"] } derive_more = { version = "1.0.0", features = ["full"] } serde = { version = "1.0", features = ["derive"] } diff --git a/pumpkin-core/src/math/position.rs b/pumpkin-core/src/math/position.rs index c324e89df..7d44f029f 100644 --- a/pumpkin-core/src/math/position.rs +++ b/pumpkin-core/src/math/position.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use super::vector3::Vector3; +#[derive(Clone, Copy)] /// Aka Block Position pub struct WorldPosition(pub Vector3); diff --git a/pumpkin-core/src/math/vector3.rs b/pumpkin-core/src/math/vector3.rs index 65da454e6..00cbd06b5 100644 --- a/pumpkin-core/src/math/vector3.rs +++ b/pumpkin-core/src/math/vector3.rs @@ -93,12 +93,16 @@ impl Neg for Vector3 { } impl From<(T, T, T)> for Vector3 { + + #[inline(always)] fn from((x, y, z): (T, T, T)) -> Self { Vector3 { x, y, z } } } impl From> for (T, T, T) { + + #[inline(always)] fn from(vector: Vector3) -> Self { (vector.x, vector.y, vector.z) } diff --git a/pumpkin-inventory/Cargo.toml b/pumpkin-inventory/Cargo.toml index 3b6c8c972..29daefc7e 100644 --- a/pumpkin-inventory/Cargo.toml +++ b/pumpkin-inventory/Cargo.toml @@ -10,4 +10,6 @@ pumpkin-world = { path = "../pumpkin-world"} num-traits = "0.2" num-derive = "0.4" thiserror = "1.0.63" -itertools = "0.13.0" \ No newline at end of file +itertools = "0.13.0" +parking_lot.workspace = true +crossbeam.workspace = true diff --git a/pumpkin-inventory/src/drag_handler.rs b/pumpkin-inventory/src/drag_handler.rs index 11d8b2f82..8479c3635 100644 --- a/pumpkin-inventory/src/drag_handler.rs +++ b/pumpkin-inventory/src/drag_handler.rs @@ -2,9 +2,10 @@ use crate::container_click::MouseDragType; use crate::{Container, InventoryError}; use itertools::Itertools; use num_traits::Euclid; +use parking_lot::{Mutex, RwLock}; use pumpkin_world::item::ItemStack; use std::collections::HashMap; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::Arc; #[derive(Debug, Default)] pub struct DragHandler(RwLock>>>); @@ -23,10 +24,7 @@ impl DragHandler { drag_type, slots: vec![], }; - let mut drags = match self.0.write() { - Ok(drags) => drags, - Err(_) => Err(InventoryError::LockError)?, - }; + let mut drags = self.0.write(); drags.insert(container_id, Arc::new(Mutex::new(drag))); Ok(()) } @@ -37,13 +35,10 @@ impl DragHandler { player: i32, slot: usize, ) -> Result<(), InventoryError> { - let drags = match self.0.read() { - Ok(drags) => drags, - Err(_) => Err(InventoryError::LockError)?, - }; + let drags = self.0.read(); match drags.get(&container_id) { Some(drag) => { - let mut drag = drag.lock().unwrap(); + let mut drag = drag.lock(); if drag.player != player { Err(InventoryError::MultiplePlayersDragging)? } @@ -68,13 +63,11 @@ impl DragHandler { return Ok(()); } - let Ok(mut drags) = self.0.write() else { - Err(InventoryError::LockError)? - }; + let mut drags = self.0.write(); let Some((_, drag)) = drags.remove_entry(container_id) else { Err(InventoryError::OutOfOrderDragging)? }; - let drag = drag.lock().unwrap(); + let drag = drag.lock(); if player != drag.player { Err(InventoryError::MultiplePlayersDragging)? diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index e1e554fae..db1de481f 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -1,5 +1,6 @@ use crate::container_click::MouseClick; use crate::player::PlayerInventory; +use crossbeam::atomic::AtomicCell; use num_derive::{FromPrimitive, ToPrimitive}; use pumpkin_world::item::ItemStack; diff --git a/pumpkin-inventory/src/open_container.rs b/pumpkin-inventory/src/open_container.rs index 25207d018..8ba82ac89 100644 --- a/pumpkin-inventory/src/open_container.rs +++ b/pumpkin-inventory/src/open_container.rs @@ -1,6 +1,7 @@ use crate::{Container, WindowType}; use pumpkin_world::item::ItemStack; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; +use parking_lot::Mutex; pub struct OpenContainer { players: Vec, diff --git a/pumpkin-inventory/src/player.rs b/pumpkin-inventory/src/player.rs index 999c9a9e1..09f8b2ff9 100644 --- a/pumpkin-inventory/src/player.rs +++ b/pumpkin-inventory/src/player.rs @@ -2,6 +2,7 @@ use std::sync::atomic::AtomicU32; use crate::container_click::MouseClick; use crate::{handle_item_change, Container, InventoryError, WindowType}; +use crossbeam::atomic::AtomicCell; use pumpkin_world::item::ItemStack; pub struct PlayerInventory { diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index dfabd2e99..a3e290c04 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -151,7 +151,7 @@ pub enum PacketError { MalformedLength, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum ConnectionState { HandShake, Status, diff --git a/pumpkin-world/Cargo.toml b/pumpkin-world/Cargo.toml index 90be69d5c..56f6dadee 100644 --- a/pumpkin-world/Cargo.toml +++ b/pumpkin-world/Cargo.toml @@ -19,6 +19,8 @@ serde_json = "1.0" static_assertions = "1.1.0" log.workspace = true +parking_lot.workspace = true + noise = "0.9.0" rand = "0.8.5" diff --git a/pumpkin-world/src/level.rs b/pumpkin-world/src/level.rs index 8707912be..f19648414 100644 --- a/pumpkin-world/src/level.rs +++ b/pumpkin-world/src/level.rs @@ -3,11 +3,12 @@ use std::{ fs::OpenOptions, io::{Read, Seek}, path::PathBuf, - sync::{Arc, Mutex}, + sync::Arc, }; use flate2::{bufread::ZlibDecoder, read::GzDecoder}; use itertools::Itertools; +use parking_lot::Mutex; use pumpkin_core::math::vector2::Vector2; use rayon::prelude::*; use thiserror::Error; @@ -152,40 +153,40 @@ impl Level { dbg!("a"); return; } - if let Ok(mut loaded_chunks) = self.loaded_chunks.lock() { - let channel = channel.clone(); - - // Check if chunks is already loaded - if loaded_chunks.contains_key(at) { - channel - .blocking_send(Ok(loaded_chunks.get(at).unwrap().clone())) - .expect("Failed sending ChunkData."); - return; - } - let at = *at; - let data = match &self.save_file { - Some(save_file) => { - match Self::read_chunk(save_file, at) { - Err(WorldError::ChunkNotGenerated(_)) => { - // This chunk was not generated yet. - Ok(self.world_gen.generate_chunk(at)) - } - // TODO this doesn't warn the user about the error. fix. - result => result, + let mut loaded_chunks = self.loaded_chunks.lock(); + let channel = channel.clone(); + + // Check if chunks is already loaded + if loaded_chunks.contains_key(at) { + channel + .blocking_send(Ok(loaded_chunks.get(at).unwrap().clone())) + .expect("Failed sending ChunkData."); + return; + } + let at = *at; + let data = match &self.save_file { + Some(save_file) => { + match Self::read_chunk(save_file, at) { + Err(WorldError::ChunkNotGenerated(_)) => { + // This chunk was not generated yet. + Ok(self.world_gen.generate_chunk(at)) } - } - None => { - // There is no savefile yet -> generate the chunks - Ok(self.world_gen.generate_chunk(at)) + // TODO this doesn't warn the user about the error. fix. + result => result, } } - .unwrap(); - let data = Arc::new(data); - channel - .blocking_send(Ok(data.clone())) - .expect("Failed sending ChunkData."); - loaded_chunks.insert(at, data); + None => { + // There is no savefile yet -> generate the chunks + Ok(self.world_gen.generate_chunk(at)) + } } + .unwrap(); + let data = Arc::new(data); + channel + .blocking_send(Ok(data.clone())) + .expect("Failed sending ChunkData."); + loaded_chunks.insert(at, data); + }) } diff --git a/pumpkin/Cargo.toml b/pumpkin/Cargo.toml index 29fa203dc..839947f0f 100644 --- a/pumpkin/Cargo.toml +++ b/pumpkin/Cargo.toml @@ -62,6 +62,8 @@ log.workspace = true # networking mio = { version = "1.0.2", features = ["os-poll", "net"]} +parking_lot.workspace = true +crossbeam.workspace = true uuid.workspace = true tokio.workspace = true rayon.workspace = true diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index 7fc6d11d1..e3b3bd754 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -42,10 +42,9 @@ impl Client { let version = handshake.protocol_version.0; self.protocol_version .store(version, std::sync::atomic::Ordering::Relaxed); - let mut connection_state = self.connection_state.lock().unwrap(); - *connection_state = handshake.next_state; - if *connection_state != ConnectionState::Status { + self.connection_state.store(handshake.next_state); + if self.connection_state.load() != ConnectionState::Status { let protocol = version; match protocol.cmp(&(CURRENT_MC_PROTOCOL as i32)) { std::cmp::Ordering::Less => { @@ -85,7 +84,7 @@ impl Client { } // default game profile, when no online mode // TODO: make offline uuid - let mut gameprofile = self.gameprofile.lock().unwrap(); + let mut gameprofile = self.gameprofile.lock(); *gameprofile = Some(GameProfile { id: login_start.uuid, name: login_start.name, @@ -125,7 +124,7 @@ impl Client { self.enable_encryption(&shared_secret) .unwrap_or_else(|e| self.kick(&e.to_string())); - let mut gameprofile = self.gameprofile.lock().unwrap(); + let mut gameprofile = self.gameprofile.lock(); if BASIC_CONFIG.online_mode { let hash = Sha1::new() @@ -133,7 +132,7 @@ impl Client { .chain_update(&server.public_key_der) .finalize(); let hash = auth_digest(&hash); - let ip = self.address.lock().unwrap().ip(); + let ip = self.address.lock().ip(); match authentication::authenticate( &gameprofile.as_ref().unwrap().name, &hash, @@ -204,7 +203,7 @@ impl Client { server: &Arc, _login_acknowledged: SLoginAcknowledged, ) { - *self.connection_state.lock().unwrap() = ConnectionState::Config; + self.connection_state.store(ConnectionState::Config); server.send_brand(self); let resource_config = &ADVANCED_CONFIG.resource_pack; @@ -239,8 +238,8 @@ impl Client { _server: &Arc, client_information: SClientInformationConfig, ) { - dbg!("got client settings"); - *self.config.lock().unwrap() = Some(PlayerConfig { + dbg!("got client settings"); + *self.config.lock() = Some(PlayerConfig { locale: client_information.locale, view_distance: client_information.view_distance, chat_mode: ChatMode::from_i32(client_information.chat_mode.into()).unwrap(), @@ -258,7 +257,7 @@ impl Client { { dbg!("got a client brand"); match String::from_utf8(plugin_message.data) { - Ok(brand) => *self.brand.lock().unwrap() = Some(brand), + Ok(brand) => *self.brand.lock() = Some(brand), Err(e) => self.kick(&e.to_string()), } } @@ -283,7 +282,7 @@ impl Client { _config_acknowledged: SAcknowledgeFinishConfig, ) { dbg!("config acknowledged"); - *self.connection_state.lock().unwrap() = ConnectionState::Play; + self.connection_state.store(ConnectionState::Play); self.make_player .store(true, std::sync::atomic::Ordering::Relaxed); } diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index 86769642e..0df08864f 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -1,6 +1,7 @@ use crate::entity::player::Player; use crate::server::Server; use itertools::Itertools; +use parking_lot::Mutex; use pumpkin_core::text::TextComponent; use pumpkin_core::GameMode; use pumpkin_inventory::container_click::{ @@ -16,11 +17,11 @@ use pumpkin_protocol::client::play::{ use pumpkin_protocol::server::play::SClickContainer; use pumpkin_protocol::slot::Slot; use pumpkin_world::item::ItemStack; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; impl Player { pub fn open_container(&self, server: &Arc, minecraft_menu_id: &str) { - let inventory = self.inventory.lock().unwrap(); + let inventory = self.inventory.lock(); inventory .state_id .store(0, std::sync::atomic::Ordering::Relaxed); @@ -28,7 +29,7 @@ impl Player { let container = self.get_open_container(server); let mut container = container .as_ref() - .map(|container| container.lock().unwrap()); + .map(|container| container.lock()); let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY .get("minecraft:menu") .unwrap() @@ -54,7 +55,7 @@ impl Player { } pub fn set_container_content(&self, container: Option<&mut Box>) { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let total_opened_containers = inventory.total_opened_containers; let container = OptionallyCombinedContainer::new(&mut inventory, container); @@ -66,7 +67,7 @@ impl Player { .collect_vec(); let carried_item = { - if let Some(item) = self.carried_item.lock().unwrap().as_ref() { + if let Some(item) = self.carried_item.load().as_ref() { item.into() } else { Slot::empty() @@ -87,7 +88,7 @@ impl Player { /// The official Minecraft client is weird, and will always just close *any* window that is opened when this gets sent pub fn close_container(&self) { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); inventory.total_opened_containers += 1; self.client .send_packet(&CCloseContainer::new(inventory.total_opened_containers)) @@ -99,7 +100,7 @@ impl Player { ) { let (id, value) = window_property.into_tuple(); self.client.send_packet(&CSetContainerProperty::new( - self.inventory.lock().unwrap().total_opened_containers, + self.inventory.lock().total_opened_containers, id, value, )); @@ -113,13 +114,12 @@ impl Player { let opened_container = self.get_open_container(server); let mut opened_container = opened_container .as_ref() - .map(|container| container.lock().unwrap()); + .map(|container| container.lock()); let drag_handler = &server.drag_handler; let state_id = self .inventory .lock() - .unwrap() .state_id .load(std::sync::atomic::Ordering::Relaxed); // This is just checking for regular desync, client hasn't done anything malicious @@ -129,7 +129,7 @@ impl Player { } if opened_container.is_some() { - if packet.window_id != self.inventory.lock().unwrap().total_opened_containers { + if packet.window_id != self.inventory.lock().total_opened_containers { return Err(InventoryError::ClosedContainerInteract(self.entity_id())); } } else if packet.window_id != 0 { @@ -191,7 +191,7 @@ impl Player { drop(opened_container); self.send_whole_container_change(server).await?; } else if let container_click::Slot::Normal(slot_index) = click.slot { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let combined_container = OptionallyCombinedContainer::new(&mut inventory, Some(&mut opened_container)); if let Some(slot) = combined_container.get_slot_excluding_inventory(slot_index) { @@ -211,15 +211,20 @@ impl Player { mouse_click: MouseClick, slot: container_click::Slot, ) -> Result<(), InventoryError> { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); match slot { - container_click::Slot::Normal(slot) => container.handle_item_change( - &mut self.carried_item.lock().unwrap(), - slot, - mouse_click, - ), + container_click::Slot::Normal(slot) => { + let mut carried_item = self.carried_item.load(); + let res = container.handle_item_change( + &mut carried_item, + slot, + mouse_click, + ); + self.carried_item.store(carried_item); + res + }, container_click::Slot::OutsideInventory => Ok(()), } } @@ -229,7 +234,7 @@ impl Player { opened_container: Option<&mut Box>, slot: container_click::Slot, ) -> Result<(), InventoryError> { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); match slot { @@ -281,7 +286,7 @@ impl Player { KeyClick::Slot(slot) => slot, KeyClick::Offhand => 45, }; - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let mut changing_item_slot = inventory.get_slot(changing_slot as usize)?.to_owned(); let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); @@ -295,13 +300,13 @@ impl Player { opened_container: Option<&mut Box>, slot: usize, ) -> Result<(), InventoryError> { - if *self.gamemode.lock().unwrap() != GameMode::Creative { + if self.gamemode.load() != GameMode::Creative { return Err(InventoryError::PermissionError); } - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); if let Some(Some(item)) = container.all_slots().get_mut(slot) { - *self.carried_item.lock().unwrap() = Some(item.to_owned()) + self.carried_item.store(Some(item.to_owned())); } Ok(()) } @@ -311,7 +316,7 @@ impl Player { opened_container: Option<&mut Box>, slot: usize, ) -> Result<(), InventoryError> { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); let mut slots = container.all_slots(); @@ -340,7 +345,7 @@ impl Player { } } } - *self.carried_item.lock().unwrap() = Some(carried_item); + self.carried_item.store(Some(carried_item)); Ok(()) } @@ -358,7 +363,7 @@ impl Player { match mouse_drag_state { MouseDragState::Start(drag_type) => { if drag_type == MouseDragType::Middle - && *self.gamemode.lock().unwrap() != GameMode::Creative + && self.gamemode.load() != GameMode::Creative { Err(InventoryError::PermissionError)? } @@ -366,15 +371,18 @@ impl Player { } MouseDragState::AddSlot(slot) => drag_handler.add_slot(container_id, player_id, slot), MouseDragState::End => { - let mut inventory = self.inventory.lock().unwrap(); + let mut inventory = self.inventory.lock(); let mut container = OptionallyCombinedContainer::new(&mut inventory, opened_container); - drag_handler.apply_drag( - &mut self.carried_item.lock().unwrap(), + let mut carried_item = self.carried_item.load(); + let res = drag_handler.apply_drag( + &mut carried_item, &mut container, &container_id, player_id, - ) + ); + self.carried_item.store(carried_item); + res } } } @@ -383,10 +391,9 @@ impl Player { let player_ids = { let open_containers = server .open_containers - .read() - .expect("open_containers is poisoned"); + .read(); open_containers - .get(&self.open_container.lock().unwrap().unwrap()) + .get(&self.open_container.load().unwrap()) .unwrap() .all_player_ids() .into_iter() @@ -403,7 +410,6 @@ impl Player { .world .current_players .lock() - .unwrap() .iter() .filter_map(|(token, player)| { if *token != player_token { @@ -428,7 +434,7 @@ impl Player { slot: Slot, ) -> Result<(), InventoryError> { for player in self.get_current_players_in_container(server).await { - let inventory = player.inventory.lock().unwrap(); + let inventory = player.inventory.lock(); let total_opened_containers = inventory.total_opened_containers; // Returns previous value @@ -451,14 +457,14 @@ impl Player { for player in players { let container = player.get_open_container(server); - let mut container = container.as_ref().map(|v| v.lock().unwrap()); + let mut container = container.as_ref().map(|v| v.lock()); player.set_container_content(container.as_deref_mut()); } Ok(()) } pub fn get_open_container(&self, server: &Server) -> Option>>> { - if let Some(id) = *self.open_container.lock().unwrap() { + if let Some(id) = self.open_container.load() { server.try_get_container(self.entity_id(), id) } else { None diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index f4e89a450..186b1a2ea 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -2,8 +2,7 @@ use std::{ io::{self, Write}, net::SocketAddr, sync::{ - atomic::{AtomicBool, AtomicI32}, - Arc, Mutex, + atomic::{AtomicBool, AtomicI32}, Arc, }, }; @@ -13,7 +12,9 @@ use crate::{ }; use authentication::GameProfile; +use crossbeam::atomic::AtomicCell; use mio::{event::Event, net::TcpStream, Token}; +use parking_lot::Mutex; use pumpkin_core::text::TextComponent; use pumpkin_protocol::{ bytebuf::{packet_id::Packet, DeserializerError}, @@ -71,7 +72,7 @@ pub struct Client { pub brand: Mutex>, pub protocol_version: AtomicI32, - pub connection_state: Mutex, + pub connection_state: AtomicCell, pub encryption: AtomicBool, pub closed: AtomicBool, pub token: Token, @@ -93,7 +94,7 @@ impl Client { brand: Mutex::new(None), token, address: Mutex::new(address), - connection_state: Mutex::new(ConnectionState::HandShake), + connection_state: AtomicCell::new(ConnectionState::HandShake), connection: Arc::new(Mutex::new(connection)), enc: Arc::new(Mutex::new(PacketEncoder::default())), dec: Arc::new(Mutex::new(PacketDecoder::default())), @@ -106,7 +107,7 @@ impl Client { /// adds a Incoming packet to the queue pub fn add_packet(&self, packet: RawPacket) { - let mut client_packets_queue = self.client_packets_queue.lock().unwrap(); + let mut client_packets_queue = self.client_packets_queue.lock(); client_packets_queue.push(packet); } @@ -120,8 +121,8 @@ impl Client { let crypt_key: [u8; 16] = shared_secret .try_into() .map_err(|_| EncryptionError::SharedWrongLength)?; - self.dec.lock().unwrap().enable_encryption(&crypt_key); - self.enc.lock().unwrap().enable_encryption(&crypt_key); + self.dec.lock().enable_encryption(&crypt_key); + self.enc.lock().enable_encryption(&crypt_key); Ok(()) } @@ -129,20 +130,18 @@ impl Client { pub fn set_compression(&self, compression: Option<(u32, u32)>) { self.dec .lock() - .unwrap() .set_compression(compression.map(|v| v.0)); - self.enc.lock().unwrap().set_compression(compression); + self.enc.lock().set_compression(compression); } /// Send a Clientbound Packet to the Client pub fn send_packet(&self, packet: &P) { // assert!(!self.closed); - let mut enc = self.enc.lock().unwrap(); + let mut enc = self.enc.lock(); enc.append_packet(packet) .unwrap_or_else(|e| self.kick(&e.to_string())); self.connection .lock() - .unwrap() .write_all(&enc.take()) .map_err(|_| PacketError::ConnectionWrite) .unwrap_or_else(|e| self.kick(&e.to_string())); @@ -151,18 +150,17 @@ impl Client { pub fn try_send_packet(&self, packet: &P) -> Result<(), PacketError> { // assert!(!self.closed); - let mut enc = self.enc.lock().unwrap(); + let mut enc = self.enc.lock(); enc.append_packet(packet)?; self.connection .lock() - .unwrap() .write_all(&enc.take()) .map_err(|_| PacketError::ConnectionWrite)?; Ok(()) } pub async fn process_packets(&self, server: &Arc) { - while let Some(mut packet) = self.client_packets_queue.lock().unwrap().pop() { + while let Some(mut packet) = self.client_packets_queue.lock().pop() { match self.handle_packet(server, &mut packet).await { Ok(_) => {} Err(e) => { @@ -182,7 +180,7 @@ impl Client { ) -> Result<(), DeserializerError> { // TODO: handle each packet's Error instead of calling .unwrap() let bytebuf = &mut packet.bytebuf; - let locked_state = self.connection_state.lock().unwrap(); + let locked_state = self.connection_state.load(); let state = locked_state.clone(); drop(locked_state); match state { @@ -291,7 +289,7 @@ impl Client { let mut bytes_read = 0; loop { let connection = self.connection.clone(); - let mut connection = connection.lock().unwrap(); + let mut connection = connection.lock(); match connection.read(&mut received_data[bytes_read..]) { Ok(0) => { // Reading 0 bytes means the other side has closed the @@ -313,7 +311,7 @@ impl Client { } if bytes_read != 0 { - let mut dec = self.dec.lock().unwrap(); + let mut dec = self.dec.lock(); dec.queue_slice(&received_data[..bytes_read]); match dec.decode() { Ok(packet) => { @@ -331,7 +329,7 @@ impl Client { /// Kicks the Client with a reason depending on the connection state pub fn kick(&self, reason: &str) { dbg!(reason); - match *self.connection_state.lock().unwrap() { + match self.connection_state.load() { ConnectionState::Login => { self.try_send_packet(&CLoginDisconnect::new( &serde_json::to_string_pretty(&reason).unwrap_or("".into()), diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 7f342d872..549f628f5 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -9,7 +9,7 @@ use crate::{ use num_traits::FromPrimitive; use pumpkin_config::ADVANCED_CONFIG; use pumpkin_core::{ - math::{position::WorldPosition, wrap_degrees}, + math::{position::WorldPosition, vector3::Vector3, wrap_degrees}, text::TextComponent, GameMode, }; @@ -46,7 +46,7 @@ impl Player { _server: &Arc, confirm_teleport: SConfirmTeleport, ) { - let mut awaiting_teleport = self.awaiting_teleport.lock().unwrap(); + let mut awaiting_teleport = self.awaiting_teleport.lock(); if let Some((id, position)) = awaiting_teleport.as_ref() { if id == &confirm_teleport.teleport_id { // we should set the pos now to that we requested in the teleport packet, Is may fixed issues when the client sended position packets while being teleported @@ -82,14 +82,14 @@ impl Player { Self::clamp_vertical(position.feet_y), Self::clamp_horizontal(position.z), ); - let mut last_position = self.last_position.lock().unwrap(); - let pos = entity.pos.lock().unwrap(); - *last_position = *pos; + let pos = entity.pos.load(); + self.last_position.store(pos); + let last_position = self.last_position.load(); entity .on_ground .store(position.ground, std::sync::atomic::Ordering::Relaxed); let entity_id = entity.entity_id; - let (x, y, z) = (*pos).into(); + let Vector3 { x, y, z } = pos; let (lastx, lasty, lastz) = (last_position.x, last_position.y, last_position.z); let world = &entity.world; @@ -142,9 +142,9 @@ impl Player { Self::clamp_vertical(position_rotation.feet_y), Self::clamp_horizontal(position_rotation.z), ); - let mut last_position = self.last_position.lock().unwrap(); - let pos = entity.pos.lock().unwrap(); - *last_position = *pos; + let pos = entity.pos.load(); + self.last_position.store(pos); + let last_position = self.last_position.load(); entity.on_ground.store( position_rotation.ground, std::sync::atomic::Ordering::Relaxed, @@ -155,10 +155,10 @@ impl Player { ); let entity_id = entity.entity_id; - let (x, y, z) = (*pos).into(); + let Vector3 {x, y, z } = pos; let (lastx, lasty, lastz) = (last_position.x, last_position.y, last_position.z); - let yaw = modulus(*entity.yaw.lock().unwrap() * 256.0 / 360.0, 256.0); - let pitch = modulus(*entity.pitch.lock().unwrap() * 256.0 / 360.0, 256.0); + let yaw = modulus(entity.yaw.load() * 256.0 / 360.0, 256.0); + let pitch = modulus(entity.pitch.load() * 256.0 / 360.0, 256.0); // let head_yaw = (entity.head_yaw * 256.0 / 360.0).floor(); let world = &entity.world; @@ -210,8 +210,8 @@ impl Player { ); // send new position to all other players let entity_id = entity.entity_id; - let yaw = modulus(*entity.yaw.lock().unwrap() * 256.0 / 360.0, 256.0); - let pitch = modulus(*entity.pitch.lock().unwrap() * 256.0 / 360.0, 256.0); + let yaw = modulus(entity.yaw.load() * 256.0 / 360.0, 256.0); + let pitch = modulus(entity.pitch.load() * 256.0 / 360.0, 256.0); // let head_yaw = modulus(entity.head_yaw * 256.0 / 360.0, 256.0); let world = &entity.world; @@ -350,7 +350,7 @@ impl Player { Hand::from_i32(client_information.main_hand.into()), ChatMode::from_i32(client_information.chat_mode.into()), ) { - *self.config.lock().unwrap() = PlayerConfig { + *self.config.lock() = PlayerConfig { locale: client_information.locale, view_distance: client_information.view_distance, chat_mode, @@ -383,19 +383,19 @@ impl Player { if let Some(player) = attacked_player { let victem_entity = &player.entity; if config.protect_creative - && *player.gamemode.lock().unwrap() == GameMode::Creative + && player.gamemode.load() == GameMode::Creative { return; } if config.knockback { - let yaw = entity.yaw.lock().unwrap(); + let yaw = entity.yaw.load(); let strength = 1.0; - let mut victem_velocity = victem_entity.velocity.lock().unwrap(); - let saved_velo = *victem_velocity; + let victem_velocity = victem_entity.velocity.load(); + let saved_velo = victem_velocity; victem_entity.knockback( strength * 0.5, - (*yaw * (PI / 180.0)).sin() as f64, - -(*yaw * (PI / 180.0)).cos() as f64, + (yaw * (PI / 180.0)).sin() as f64, + -(yaw * (PI / 180.0)).cos() as f64, ); let packet = &CEntityVelocity::new( &entity_id, @@ -403,16 +403,16 @@ impl Player { victem_velocity.y as f32, victem_velocity.z as f32, ); - let mut velocity = entity.velocity.lock().unwrap(); - *velocity = velocity.multiply(0.6, 1.0, 0.6); + let velocity = entity.velocity.load(); + victem_entity.velocity.store(velocity.multiply(0.6, 1.0, 0.6)); - *victem_velocity = saved_velo; + victem_entity.velocity.store(saved_velo); player.client.send_packet(packet); } if config.hurt_animation { world.broadcast_packet_all(&CHurtAnimation::new( &entity_id, - *entity.yaw.lock().unwrap(), + entity.yaw.load(), )) } if config.swing {} @@ -441,7 +441,7 @@ impl Player { } // TODO: do validation // TODO: Config - if *self.gamemode.lock().unwrap() == GameMode::Creative { + if self.gamemode.load() == GameMode::Creative { let location = player_action.location; // Block break & block break sound // TODO: currently this is always dirt replace it @@ -509,7 +509,7 @@ impl Player { } if let Some(face) = BlockFace::from_i32(use_item_on.face.0) { - if let Some(item) = self.inventory.lock().unwrap().held_item() { + if let Some(item) = self.inventory.lock().held_item() { let minecraft_id = global_registry::find_minecraft_id( global_registry::ITEM_REGISTRY, item.item_id, @@ -545,7 +545,7 @@ impl Player { if !(0..=8).contains(&slot) { self.kick(TextComponent::text("Invalid held slot")) } - self.inventory.lock().unwrap().set_selected(slot as usize); + self.inventory.lock().set_selected(slot as usize); } pub fn handle_set_creative_slot( @@ -553,10 +553,10 @@ impl Player { _server: &Arc, packet: SSetCreativeSlot, ) -> Result<(), InventoryError> { - if *self.gamemode.lock().unwrap() != GameMode::Creative { + if self.gamemode.load() != GameMode::Creative { return Err(InventoryError::PermissionError); } - self.inventory.lock().unwrap().set_slot( + self.inventory.lock().set_slot( packet.slot as usize, packet.clicked_item.to_item(), false, @@ -570,19 +570,17 @@ impl Player { // window_id 0 represents both 9x1 Generic AND inventory here self.inventory .lock() - .unwrap() .state_id .store(0, std::sync::atomic::Ordering::Relaxed); - let mut open_container = self.open_container.lock().unwrap(); - if let Some(id) = *open_container { + let open_container = self.open_container.load(); + if let Some(id) = open_container { let mut open_containers = server .open_containers - .write() - .expect("open_containers got poisoned"); + .write(); if let Some(container) = open_containers.get_mut(&id) { container.remove_player(self.entity_id()) } - *open_container = None; + self.open_container.store(None); } let Some(_window_type) = WindowType::from_u8(packet.window_id) else { self.kick(TextComponent::text("Invalid window ID")); diff --git a/pumpkin/src/commands/cmd_echest.rs b/pumpkin/src/commands/cmd_echest.rs index fe55c9608..2d234e3cf 100644 --- a/pumpkin/src/commands/cmd_echest.rs +++ b/pumpkin/src/commands/cmd_echest.rs @@ -11,12 +11,11 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> { CommandTree::new(NAMES, DESCRIPTION).execute(&|sender, server, _| { if let Some(player) = sender.as_mut_player() { let entity_id = player.entity_id(); - *player.open_container.lock().unwrap() = Some(0); + player.open_container.store(Some(0)); { let mut open_containers = server .open_containers - .write() - .expect("open_containers got poisoned"); + .write(); match open_containers.get_mut(&0) { Some(ender_chest) => { ender_chest.add_player(entity_id); diff --git a/pumpkin/src/commands/cmd_gamemode.rs b/pumpkin/src/commands/cmd_gamemode.rs index 92600d395..ce48f8d91 100644 --- a/pumpkin/src/commands/cmd_gamemode.rs +++ b/pumpkin/src/commands/cmd_gamemode.rs @@ -65,7 +65,7 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> { let gamemode = parse_arg_gamemode(args)?; return if let Player(target) = sender { - if *target.gamemode.lock().unwrap() == gamemode { + if target.gamemode.load() == gamemode { target.send_system_message(TextComponent::text(&format!( "You already in {:?} gamemode", gamemode @@ -89,7 +89,7 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> { let gamemode = parse_arg_gamemode(args)?; let target = parse_arg_player(sender, ARG_TARGET, args)?; - if *target.gamemode.lock().unwrap() == gamemode { + if target.gamemode.load() == gamemode { target.send_system_message(TextComponent::text(&format!( "You already in {:?} gamemode", gamemode diff --git a/pumpkin/src/entity/mod.rs b/pumpkin/src/entity/mod.rs index 132dfedf0..982de2ad1 100644 --- a/pumpkin/src/entity/mod.rs +++ b/pumpkin/src/entity/mod.rs @@ -1,5 +1,6 @@ -use std::sync::{atomic::AtomicBool, Arc, Mutex}; +use std::sync::{atomic::AtomicBool, Arc}; +use crossbeam::atomic::AtomicCell; use pumpkin_core::math::{ get_section_cord, position::WorldPosition, vector2::Vector2, vector3::Vector3, }; @@ -18,24 +19,24 @@ pub struct Entity { pub entity_type: EntityType, pub world: Arc, - pub pos: Mutex>, - pub block_pos: Mutex, - pub chunk_pos: Mutex>, + pub pos: AtomicCell>, + pub block_pos: AtomicCell, + pub chunk_pos: AtomicCell>, pub sneaking: AtomicBool, pub sprinting: AtomicBool, pub fall_flying: AtomicBool, - pub velocity: Mutex>, + pub velocity: AtomicCell>, // Should be not trusted pub on_ground: AtomicBool, - pub yaw: Mutex, - pub head_yaw: Mutex, - pub pitch: Mutex, + pub yaw: AtomicCell, + pub head_yaw: AtomicCell, + pub pitch: AtomicCell, // TODO: Change this in diffrent poses pub standing_eye_height: f32, - pub pose: Mutex, + pub pose: AtomicCell, } impl Entity { @@ -49,41 +50,41 @@ impl Entity { entity_id, entity_type, on_ground: AtomicBool::new(false), - pos: Mutex::new(Vector3::new(0.0, 0.0, 0.0)), - block_pos: Mutex::new(WorldPosition(Vector3::new(0, 0, 0))), - chunk_pos: Mutex::new(Vector2::new(0, 0)), + pos: AtomicCell::new(Vector3::new(0.0, 0.0, 0.0)), + block_pos: AtomicCell::new(WorldPosition(Vector3::new(0, 0, 0))), + chunk_pos: AtomicCell::new(Vector2::new(0, 0)), sneaking: AtomicBool::new(false), world, sprinting: AtomicBool::new(false), fall_flying: AtomicBool::new(false), - yaw: Mutex::new(0.0), - head_yaw: Mutex::new(0.0), - pitch: Mutex::new(0.0), - velocity: Mutex::new(Vector3::new(0.0, 0.0, 0.0)), + yaw: AtomicCell::new(0.0), + head_yaw: AtomicCell::new(0.0), + pitch: AtomicCell::new(0.0), + velocity: AtomicCell::new(Vector3::new(0.0, 0.0, 0.0)), standing_eye_height, - pose: Mutex::new(EntityPose::Standing), + pose: AtomicCell::new(EntityPose::Standing), } } pub fn set_pos(&self, x: f64, y: f64, z: f64) { - let mut pos = self.pos.lock().unwrap(); + let pos = self.pos.load(); if pos.x != x || pos.y != y || pos.z != z { - *pos = Vector3::new(x, y, 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 mut block_pos = self.block_pos.lock().unwrap(); + 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 { - *block_pos = WorldPosition(Vector3::new(i, j, k)); + self.block_pos.store(WorldPosition(Vector3::new(i, j, k))); - let mut chunk_pos = self.chunk_pos.lock().unwrap(); + let chunk_pos = self.chunk_pos.load(); if get_section_cord(i) != chunk_pos.x || get_section_cord(k) != chunk_pos.z { - *chunk_pos = Vector2::new( + self.chunk_pos.store(Vector2::new( get_section_cord(block_pos_vec.x), get_section_cord(block_pos_vec.z), - ); + )); } } } @@ -91,8 +92,8 @@ impl Entity { pub fn set_rotation(&self, yaw: f32, pitch: f32) { // TODO - *self.yaw.lock().unwrap() = yaw; - *self.pitch.lock().unwrap() = pitch + self.yaw.store(yaw); + self.pitch.store(pitch); } pub async fn remove(&mut self) { @@ -109,8 +110,8 @@ impl Entity { } let var8 = Vector3::new(x, 0.0, z).normalize() * strength; - let mut velocity = self.velocity.lock().unwrap(); - *velocity = Vector3::new( + let velocity = self.velocity.load(); + self.velocity.store(Vector3::new( velocity.x / 2.0 - var8.x, if self.on_ground.load(std::sync::atomic::Ordering::Relaxed) { (velocity.y / 2.0 + strength).min(0.4) @@ -118,7 +119,7 @@ impl Entity { velocity.y }, velocity.z / 2.0 - var8.z, - ); + )); } pub async fn set_sneaking(&self, sneaking: bool) { @@ -171,7 +172,7 @@ impl Entity { } pub async fn set_pose(&self, pose: EntityPose) { - *self.pose.lock().unwrap() = pose; + self.pose.store(pose); let pose = pose as i32; let packet = CSetEntityMetadata::::new( self.entity_id.into(), diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 67ed05e8f..67f0ee774 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -1,10 +1,12 @@ use std::sync::{ atomic::{AtomicI32, AtomicU8}, - Arc, Mutex, + Arc, }; +use crossbeam::atomic::AtomicCell; use num_derive::FromPrimitive; use num_traits::ToPrimitive; +use parking_lot::Mutex; use pumpkin_core::{ math::{boundingbox::BoundingBox, position::WorldPosition, vector3::Vector3}, text::TextComponent, @@ -67,18 +69,18 @@ pub struct Player { pub client: Client, pub config: Mutex, /// Current gamemode - pub gamemode: Mutex, + pub gamemode: AtomicCell, // TODO: prbly should put this into an Living Entitiy or something - pub health: Mutex, + pub health: AtomicCell, pub food: AtomicI32, - pub food_saturation: Mutex, + pub food_saturation: AtomicCell, pub inventory: Mutex, - pub open_container: Mutex>, - pub carried_item: Mutex>, + pub open_container: AtomicCell>, + pub carried_item: AtomicCell>, /// send `send_abilties_update` when changed pub abilities: PlayerAbilities, - pub last_position: Mutex>, + pub last_position: AtomicCell>, // TODO: This is currently unused, We have to calculate the block breaking speed our own and then break the block our own if its done pub current_block_destroy_stage: AtomicU8, @@ -87,12 +89,12 @@ pub struct Player { // Current awaiting teleport id and location, None if did not teleport pub awaiting_teleport: Mutex)>>, - pub watched_section: Mutex>, + pub watched_section: AtomicCell>, } impl Player { pub fn new(client: Client, world: Arc, entity_id: EntityId, gamemode: GameMode) -> Self { - let gameprofile = match client.gameprofile.lock().unwrap().clone() { + let gameprofile = match client.gameprofile.lock().clone() { Some(profile) => profile, None => { log::error!("No gameprofile?. Impossible"); @@ -104,7 +106,7 @@ impl Player { } } }; - let config = client.config.lock().unwrap().clone().unwrap_or_default(); + let config = client.config.lock().clone().unwrap_or_default(); Self { entity: Entity::new(entity_id, world, EntityType::Player, 1.62), config: Mutex::new(config), @@ -112,18 +114,18 @@ impl Player { client, awaiting_teleport: Mutex::new(None), // TODO: Load this from previous instance - health: Mutex::new(20.0), + health: AtomicCell::new(20.0), food: AtomicI32::new(20), - food_saturation: Mutex::new(20.0), + food_saturation: AtomicCell::new(20.0), current_block_destroy_stage: AtomicU8::new(0), inventory: Mutex::new(PlayerInventory::new()), - open_container: Mutex::new(None), - carried_item: Mutex::new(None), + open_container: AtomicCell::new(None), + carried_item: AtomicCell::new(None), teleport_id_count: AtomicI32::new(0), abilities: PlayerAbilities::default(), - gamemode: Mutex::new(gamemode), - watched_section: Mutex::new(Vector3::new(0, 0, 0)), - last_position: Mutex::new(Vector3::new(0.0, 0.0, 0.0)), + gamemode: AtomicCell::new(gamemode), + watched_section: AtomicCell::new(Vector3::new(0, 0, 0)), + last_position: AtomicCell::new(Vector3::new(0.0, 0.0, 0.0)), } } @@ -173,7 +175,7 @@ impl Player { let entity = &self.entity; entity.set_pos(x, y, z); entity.set_rotation(yaw, pitch); - *self.awaiting_teleport.lock().unwrap() = Some((teleport_id.into(), Vector3::new(x, y, z))); + *self.awaiting_teleport.lock() = Some((teleport_id.into(), Vector3::new(x, y, z))); self.client.send_packet(&CSyncPlayerPosition::new( x, y, @@ -186,7 +188,7 @@ impl Player { } pub fn block_interaction_range(&self) -> f64 { - if *self.gamemode.lock().unwrap() == GameMode::Creative { + if self.gamemode.load() == GameMode::Creative { 5.0 } else { 4.5 @@ -196,7 +198,7 @@ impl Player { pub fn can_interact_with_block_at(&self, pos: &WorldPosition, additional_range: f64) -> bool { let d = self.block_interaction_range() + additional_range; let box_pos = BoundingBox::from_block(pos); - let entity_pos = self.entity.pos.lock().unwrap(); + let entity_pos = self.entity.pos.load(); let standing_eye_height = self.entity.standing_eye_height; box_pos.squared_magnitude(Vector3 { x: entity_pos.x, @@ -207,7 +209,7 @@ impl Player { /// Kicks the Client with a reason depending on the connection state pub fn kick(&self, reason: TextComponent) { - assert!(*self.client.connection_state.lock().unwrap() == ConnectionState::Play); + assert!(self.client.connection_state.load() == ConnectionState::Play); assert!(!self .client .closed @@ -225,19 +227,19 @@ impl Player { } pub fn update_health(&self, health: f32, food: i32, food_saturation: f32) { - *self.health.lock().unwrap() = health; + self.health.store(health); self.food.store(food, std::sync::atomic::Ordering::Relaxed); - *self.food_saturation.lock().unwrap() = food_saturation; + self.food_saturation.store(food_saturation); } pub fn set_gamemode(&self, gamemode: GameMode) { // We could send the same gamemode without problems. But why waste bandwidth ? - let mut current_gamemode = self.gamemode.lock().unwrap(); + let current_gamemode = self.gamemode.load(); assert!( - *current_gamemode != gamemode, + current_gamemode != gamemode, "Setting the same gamemode as already is" ); - *current_gamemode = gamemode; + self.gamemode.store(gamemode); // So a little story time. I actually made an abitlties_from_gamemode function. I looked at vanilla and they always send the abilties from the gamemode. But the funny thing actually is. That the client // does actually use the same method and set the abilties when receiving the CGameEvent gamemode packet. Just Mojang nonsense self.entity @@ -261,7 +263,7 @@ impl Player { impl Player { pub async fn process_packets(&self, server: &Arc) { - let mut packets = self.client.client_packets_queue.lock().unwrap(); + let mut packets = self.client.client_packets_queue.lock(); while let Some(mut packet) = packets.pop() { match self.handle_play_packet(server, &mut packet).await { Ok(_) => {} diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index 8a00ebbb4..79f5382e8 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -172,7 +172,7 @@ fn main() -> io::Result<()> { dbg!("a"); player.remove().await; dbg!("b"); - let connection = &mut player.client.connection.lock().unwrap(); + let connection = &mut player.client.connection.lock(); dbg!("c"); poll.registry().deregister(connection.by_ref())?; @@ -201,7 +201,7 @@ fn main() -> io::Result<()> { if done || make_player { if let Some(client) = clients.remove(&token) { if done { - let connection = &mut client.connection.lock().unwrap(); + let connection = &mut client.connection.lock(); poll.registry().deregister(connection.by_ref())?; } else if make_player { let token = client.token; diff --git a/pumpkin/src/proxy/velocity.rs b/pumpkin/src/proxy/velocity.rs index 869f470f2..e97e84c97 100644 --- a/pumpkin/src/proxy/velocity.rs +++ b/pumpkin/src/proxy/velocity.rs @@ -62,7 +62,7 @@ pub fn receive_plugin_response( } // TODO: no unwrap let addr: SocketAddr = buf.get_string().unwrap().parse().unwrap(); - *client.address.lock().unwrap() = addr; + *client.address.lock() = addr; todo!() } else { client.kick("This server requires you to connect with Velocity.") diff --git a/pumpkin/src/server/mod.rs b/pumpkin/src/server/mod.rs index 986842d60..2756f9194 100644 --- a/pumpkin/src/server/mod.rs +++ b/pumpkin/src/server/mod.rs @@ -1,6 +1,7 @@ use base64::{engine::general_purpose, Engine}; use image::GenericImageView; use mio::Token; +use parking_lot::{Mutex, RwLock}; use pumpkin_config::{BasicConfiguration, BASIC_CONFIG}; use pumpkin_core::GameMode; use pumpkin_entity::EntityId; @@ -11,13 +12,11 @@ use pumpkin_protocol::{ }; use pumpkin_world::dimension::Dimension; use std::collections::HashMap; -use std::sync::RwLock; use std::{ io::Cursor, path::Path, sync::{ - atomic::{AtomicI32, Ordering}, - Arc, Mutex, + atomic::{AtomicI32, Ordering}, Arc, }, time::Duration, }; @@ -143,8 +142,7 @@ impl Server { ) -> Option>>> { let open_containers = self .open_containers - .read() - .expect("open_containers is poisoned"); + .read(); open_containers .get(&container_id)? .try_open(player_id) diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 253fa27b4..11e1bae85 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -1,12 +1,13 @@ use std::{ collections::HashMap, - sync::{Arc, Mutex}, + sync::Arc, }; pub mod player_chunker; use mio::Token; use num_traits::ToPrimitive; +use parking_lot::Mutex; use pumpkin_config::BasicConfiguration; use pumpkin_core::math::vector2::Vector2; use pumpkin_entity::{entity_type::EntityType, EntityId}; @@ -45,7 +46,7 @@ impl World { where P: ClientPacket, { - let current_players = self.current_players.lock().unwrap(); + let current_players = self.current_players.lock(); for (_, player) in current_players.iter() { player.client.send_packet(packet); } @@ -56,7 +57,7 @@ impl World { where P: ClientPacket, { - let current_players = self.current_players.lock().unwrap(); + let current_players = self.current_players.lock(); for (_, player) in current_players.iter().filter(|c| !except.contains(c.0)) { player.client.send_packet(packet); } @@ -65,7 +66,7 @@ impl World { pub async fn spawn_player(&self, base_config: &BasicConfiguration, player: Arc) { // This code follows the vanilla packet order let entity_id = player.entity_id(); - let gamemode = player.gamemode.lock().unwrap(); + let gamemode = player.gamemode.load(); log::debug!("spawning player, entity id {}", entity_id); // login packet for our new player @@ -126,7 +127,6 @@ impl World { for (_, playerr) in self .current_players .lock() - .unwrap() .iter() .filter(|(c, _)| **c != player.client.token) { @@ -173,12 +173,11 @@ impl World { for (_, existing_player) in self .current_players .lock() - .unwrap() .iter() .filter(|c| c.0 != &token) { let entity = &existing_player.entity; - let pos = entity.pos.lock().unwrap(); + let pos = entity.pos.load(); let gameprofile = &existing_player.gameprofile; player.client.send_packet(&CSpawnEntity::new( existing_player.entity_id().into(), @@ -187,9 +186,9 @@ impl World { pos.x, pos.y, pos.z, - *entity.yaw.lock().unwrap(), - *entity.pitch.lock().unwrap(), - *entity.head_yaw.lock().unwrap(), + entity.yaw.load(), + entity.pitch.load(), + entity.head_yaw.load(), 0.into(), 0.0, 0.0, @@ -198,7 +197,7 @@ impl World { } // entity meta data // set skin parts - if let Some(config) = player.client.config.lock().unwrap().as_ref() { + if let Some(config) = player.client.config.lock().as_ref() { let packet = CSetEntityMetadata::new( entity_id.into(), Metadata::new(17, VarInt(0), config.skin_parts), @@ -221,7 +220,7 @@ impl World { let closed = client.closed.load(std::sync::atomic::Ordering::Relaxed); let chunks = Arc::new(chunks); tokio::task::spawn_blocking(move || { - level.lock().unwrap().fetch_chunks(&chunks, sender, closed) + level.lock().fetch_chunks(&chunks, sender, closed) }); while let Some(chunk_data) = chunk_receiver.recv().await { @@ -254,7 +253,6 @@ impl World { for (_, player) in self .current_players .lock() - .unwrap() .iter() .filter(|c| c.0 != &from.client.token) { @@ -266,13 +264,12 @@ impl World { } pub fn add_player(&self, token: Token, player: Arc) { - self.current_players.lock().unwrap().insert(token, player); + self.current_players.lock().insert(token, player); } pub fn remove_player(&self, player: &Player) { self.current_players .lock() - .unwrap() .remove(&player.client.token) .unwrap(); let uuid = player.gameprofile.id; diff --git a/pumpkin/src/world/player_chunker.rs b/pumpkin/src/world/player_chunker.rs index 0a8464883..d6fb893aa 100644 --- a/pumpkin/src/world/player_chunker.rs +++ b/pumpkin/src/world/player_chunker.rs @@ -15,16 +15,15 @@ fn get_view_distance(player: &Player) -> i8 { player .config .lock() - .unwrap() .view_distance .clamp(2, BASIC_CONFIG.view_distance as i8) } pub async fn player_join(world: &World, player: Arc) { - let new_watched = chunk_section_from_pos(&player.entity.block_pos.lock().unwrap()); - let mut watched_section = player.watched_section.lock().unwrap(); - *watched_section = new_watched; - let chunk_pos = player.entity.chunk_pos.lock().unwrap(); + let new_watched = chunk_section_from_pos(&player.entity.block_pos.load()); + player.watched_section.store(new_watched); + let watched_section = new_watched; + let chunk_pos = player.entity.chunk_pos.load(); player.client.send_packet(&CCenterChunk { chunk_x: chunk_pos.x.into(), chunk_z: chunk_pos.z.into(), @@ -58,10 +57,10 @@ pub async fn player_join(world: &World, player: Arc) { } pub async fn update_position(entity: &Entity, player: &Player) { - let mut current_watched = player.watched_section.lock().unwrap(); - let new_watched = chunk_section_from_pos(&entity.block_pos.lock().unwrap()); - if *current_watched != new_watched { - let chunk_pos = entity.chunk_pos.lock().unwrap(); + let current_watched = player.watched_section.load(); + let new_watched = chunk_section_from_pos(&entity.block_pos.load()); + if current_watched != new_watched { + let chunk_pos = entity.chunk_pos.load(); player.client.send_packet(&CCenterChunk { chunk_x: chunk_pos.x.into(), chunk_z: chunk_pos.z.into(), @@ -74,7 +73,7 @@ pub async fn update_position(entity: &Entity, player: &Player) { ); let new_cylindrical = Cylindrical::new(Vector2::new(chunk_pos.x, chunk_pos.z), view_distance); - *current_watched = new_watched; + player.watched_section.store(new_watched); let mut loading_chunks = Vec::new(); Cylindrical::for_each_changed_chunk( old_cylindrical, From d176fbd37e546ff9e8a775721bd1c850c0f59633 Mon Sep 17 00:00:00 2001 From: Asurar0 Date: Wed, 11 Sep 2024 22:56:03 +0200 Subject: [PATCH 2/3] fix fmt --- pumpkin-core/src/math/vector3.rs | 2 -- pumpkin-inventory/src/open_container.rs | 2 +- pumpkin-world/src/level.rs | 1 - pumpkin/src/client/client_packet.rs | 2 +- pumpkin/src/client/container.rs | 23 ++++++----------------- pumpkin/src/client/mod.rs | 7 +++---- pumpkin/src/client/player_packet.rs | 18 ++++++++---------- pumpkin/src/commands/cmd_echest.rs | 4 +--- pumpkin/src/server/mod.rs | 7 +++---- pumpkin/src/world/mod.rs | 16 +++------------- 10 files changed, 26 insertions(+), 56 deletions(-) diff --git a/pumpkin-core/src/math/vector3.rs b/pumpkin-core/src/math/vector3.rs index 00cbd06b5..d8f0b3916 100644 --- a/pumpkin-core/src/math/vector3.rs +++ b/pumpkin-core/src/math/vector3.rs @@ -93,7 +93,6 @@ impl Neg for Vector3 { } impl From<(T, T, T)> for Vector3 { - #[inline(always)] fn from((x, y, z): (T, T, T)) -> Self { Vector3 { x, y, z } @@ -101,7 +100,6 @@ impl From<(T, T, T)> for Vector3 { } impl From> for (T, T, T) { - #[inline(always)] fn from(vector: Vector3) -> Self { (vector.x, vector.y, vector.z) diff --git a/pumpkin-inventory/src/open_container.rs b/pumpkin-inventory/src/open_container.rs index 8ba82ac89..261ba3b74 100644 --- a/pumpkin-inventory/src/open_container.rs +++ b/pumpkin-inventory/src/open_container.rs @@ -1,7 +1,7 @@ use crate::{Container, WindowType}; +use parking_lot::Mutex; use pumpkin_world::item::ItemStack; use std::sync::Arc; -use parking_lot::Mutex; pub struct OpenContainer { players: Vec, diff --git a/pumpkin-world/src/level.rs b/pumpkin-world/src/level.rs index f19648414..e44448bb8 100644 --- a/pumpkin-world/src/level.rs +++ b/pumpkin-world/src/level.rs @@ -186,7 +186,6 @@ impl Level { .blocking_send(Ok(data.clone())) .expect("Failed sending ChunkData."); loaded_chunks.insert(at, data); - }) } diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index e3b3bd754..45a016f02 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -238,7 +238,7 @@ impl Client { _server: &Arc, client_information: SClientInformationConfig, ) { - dbg!("got client settings"); + dbg!("got client settings"); *self.config.lock() = Some(PlayerConfig { locale: client_information.locale, view_distance: client_information.view_distance, diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index 0df08864f..dc15a21cd 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -27,9 +27,7 @@ impl Player { .store(0, std::sync::atomic::Ordering::Relaxed); let total_opened_containers = inventory.total_opened_containers; let container = self.get_open_container(server); - let mut container = container - .as_ref() - .map(|container| container.lock()); + let mut container = container.as_ref().map(|container| container.lock()); let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY .get("minecraft:menu") .unwrap() @@ -112,9 +110,7 @@ impl Player { packet: SClickContainer, ) -> Result<(), InventoryError> { let opened_container = self.get_open_container(server); - let mut opened_container = opened_container - .as_ref() - .map(|container| container.lock()); + let mut opened_container = opened_container.as_ref().map(|container| container.lock()); let drag_handler = &server.drag_handler; let state_id = self @@ -217,14 +213,10 @@ impl Player { match slot { container_click::Slot::Normal(slot) => { let mut carried_item = self.carried_item.load(); - let res = container.handle_item_change( - &mut carried_item, - slot, - mouse_click, - ); + let res = container.handle_item_change(&mut carried_item, slot, mouse_click); self.carried_item.store(carried_item); res - }, + } container_click::Slot::OutsideInventory => Ok(()), } } @@ -362,8 +354,7 @@ impl Player { .unwrap_or(player_id as u64); match mouse_drag_state { MouseDragState::Start(drag_type) => { - if drag_type == MouseDragType::Middle - && self.gamemode.load() != GameMode::Creative + if drag_type == MouseDragType::Middle && self.gamemode.load() != GameMode::Creative { Err(InventoryError::PermissionError)? } @@ -389,9 +380,7 @@ impl Player { async fn get_current_players_in_container(&self, server: &Server) -> Vec> { let player_ids = { - let open_containers = server - .open_containers - .read(); + let open_containers = server.open_containers.read(); open_containers .get(&self.open_container.load().unwrap()) .unwrap() diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 186b1a2ea..b6201918a 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -2,7 +2,8 @@ use std::{ io::{self, Write}, net::SocketAddr, sync::{ - atomic::{AtomicBool, AtomicI32}, Arc, + atomic::{AtomicBool, AtomicI32}, + Arc, }, }; @@ -128,9 +129,7 @@ impl Client { // Compression threshold, Compression level pub fn set_compression(&self, compression: Option<(u32, u32)>) { - self.dec - .lock() - .set_compression(compression.map(|v| v.0)); + self.dec.lock().set_compression(compression.map(|v| v.0)); self.enc.lock().set_compression(compression); } diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 549f628f5..0cb74053c 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -155,7 +155,7 @@ impl Player { ); let entity_id = entity.entity_id; - let Vector3 {x, y, z } = pos; + let Vector3 { x, y, z } = pos; let (lastx, lasty, lastz) = (last_position.x, last_position.y, last_position.z); let yaw = modulus(entity.yaw.load() * 256.0 / 360.0, 256.0); let pitch = modulus(entity.pitch.load() * 256.0 / 360.0, 256.0); @@ -404,7 +404,9 @@ impl Player { victem_velocity.z as f32, ); let velocity = entity.velocity.load(); - victem_entity.velocity.store(velocity.multiply(0.6, 1.0, 0.6)); + victem_entity + .velocity + .store(velocity.multiply(0.6, 1.0, 0.6)); victem_entity.velocity.store(saved_velo); player.client.send_packet(packet); @@ -556,11 +558,9 @@ impl Player { if self.gamemode.load() != GameMode::Creative { return Err(InventoryError::PermissionError); } - self.inventory.lock().set_slot( - packet.slot as usize, - packet.clicked_item.to_item(), - false, - ) + self.inventory + .lock() + .set_slot(packet.slot as usize, packet.clicked_item.to_item(), false) } // TODO: @@ -574,9 +574,7 @@ impl Player { .store(0, std::sync::atomic::Ordering::Relaxed); let open_container = self.open_container.load(); if let Some(id) = open_container { - let mut open_containers = server - .open_containers - .write(); + let mut open_containers = server.open_containers.write(); if let Some(container) = open_containers.get_mut(&id) { container.remove_player(self.entity_id()) } diff --git a/pumpkin/src/commands/cmd_echest.rs b/pumpkin/src/commands/cmd_echest.rs index 2d234e3cf..690fff41c 100644 --- a/pumpkin/src/commands/cmd_echest.rs +++ b/pumpkin/src/commands/cmd_echest.rs @@ -13,9 +13,7 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> { let entity_id = player.entity_id(); player.open_container.store(Some(0)); { - let mut open_containers = server - .open_containers - .write(); + let mut open_containers = server.open_containers.write(); match open_containers.get_mut(&0) { Some(ender_chest) => { ender_chest.add_player(entity_id); diff --git a/pumpkin/src/server/mod.rs b/pumpkin/src/server/mod.rs index 2756f9194..04949582a 100644 --- a/pumpkin/src/server/mod.rs +++ b/pumpkin/src/server/mod.rs @@ -16,7 +16,8 @@ use std::{ io::Cursor, path::Path, sync::{ - atomic::{AtomicI32, Ordering}, Arc, + atomic::{AtomicI32, Ordering}, + Arc, }, time::Duration, }; @@ -140,9 +141,7 @@ impl Server { player_id: EntityId, container_id: u64, ) -> Option>>> { - let open_containers = self - .open_containers - .read(); + let open_containers = self.open_containers.read(); open_containers .get(&container_id)? .try_open(player_id) diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 11e1bae85..49d6720b5 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -1,7 +1,4 @@ -use std::{ - collections::HashMap, - sync::Arc, -}; +use std::{collections::HashMap, sync::Arc}; pub mod player_chunker; @@ -170,12 +167,7 @@ impl World { ); // spawn players for our client let token = player.client.token; - for (_, existing_player) in self - .current_players - .lock() - .iter() - .filter(|c| c.0 != &token) - { + for (_, existing_player) in self.current_players.lock().iter().filter(|c| c.0 != &token) { let entity = &existing_player.entity; let pos = entity.pos.load(); let gameprofile = &existing_player.gameprofile; @@ -219,9 +211,7 @@ impl World { let level = self.level.clone(); let closed = client.closed.load(std::sync::atomic::Ordering::Relaxed); let chunks = Arc::new(chunks); - tokio::task::spawn_blocking(move || { - level.lock().fetch_chunks(&chunks, sender, closed) - }); + tokio::task::spawn_blocking(move || level.lock().fetch_chunks(&chunks, sender, closed)); while let Some(chunk_data) = chunk_receiver.recv().await { // dbg!(chunk_pos); From 2e99877a6cc15ce8024bd7dd1c7b21ac3f5f69cd Mon Sep 17 00:00:00 2001 From: Asurar0 Date: Wed, 11 Sep 2024 23:01:09 +0200 Subject: [PATCH 3/3] fix warnings --- pumpkin-inventory/src/lib.rs | 1 - pumpkin-inventory/src/player.rs | 1 - pumpkin/src/client/mod.rs | 5 +---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index db1de481f..e1e554fae 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -1,6 +1,5 @@ use crate::container_click::MouseClick; use crate::player::PlayerInventory; -use crossbeam::atomic::AtomicCell; use num_derive::{FromPrimitive, ToPrimitive}; use pumpkin_world::item::ItemStack; diff --git a/pumpkin-inventory/src/player.rs b/pumpkin-inventory/src/player.rs index 09f8b2ff9..999c9a9e1 100644 --- a/pumpkin-inventory/src/player.rs +++ b/pumpkin-inventory/src/player.rs @@ -2,7 +2,6 @@ use std::sync::atomic::AtomicU32; use crate::container_click::MouseClick; use crate::{handle_item_change, Container, InventoryError, WindowType}; -use crossbeam::atomic::AtomicCell; use pumpkin_world::item::ItemStack; pub struct PlayerInventory { diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index b6201918a..bcdb72255 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -179,10 +179,7 @@ impl Client { ) -> Result<(), DeserializerError> { // TODO: handle each packet's Error instead of calling .unwrap() let bytebuf = &mut packet.bytebuf; - let locked_state = self.connection_state.load(); - let state = locked_state.clone(); - drop(locked_state); - match state { + match self.connection_state.load() { pumpkin_protocol::ConnectionState::HandShake => match packet.id.0 { SHandShake::PACKET_ID => { self.handle_handshake(server, SHandShake::read(bytebuf)?);