From 9f78b3f4a7229033a3f5acaad6c8fffbe24e3e75 Mon Sep 17 00:00:00 2001 From: Honbra Date: Mon, 14 Nov 2022 20:25:59 +0100 Subject: [PATCH 1/6] Military-grade server implementation (#40) * Military-grade server implementation * Add doc comments --- azalea-protocol/src/connect.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/azalea-protocol/src/connect.rs b/azalea-protocol/src/connect.rs index 37df0f08..00685d3c 100755 --- a/azalea-protocol/src/connect.rs +++ b/azalea-protocol/src/connect.rs @@ -302,7 +302,8 @@ where R1: ProtocolPacket + Debug, W1: ProtocolPacket + Debug, { - fn from(connection: Connection) -> Connection + /// Creates a `Connection` of a type from a `Connection` of another type. Useful for servers or custom packets. + pub fn from(connection: Connection) -> Connection where R2: ProtocolPacket + Debug, W2: ProtocolPacket + Debug, @@ -323,4 +324,25 @@ where }, } } + + /// Convert an existing `TcpStream` into a `Connection`. Useful for servers. + pub fn wrap(stream: TcpStream) -> Connection { + let (read_stream, write_stream) = stream.into_split(); + + Connection { + reader: ReadConnection { + read_stream, + buffer: BytesMut::new(), + compression_threshold: None, + dec_cipher: None, + _reading: PhantomData, + }, + writer: WriteConnection { + write_stream, + compression_threshold: None, + enc_cipher: None, + _writing: PhantomData, + }, + } + } } From 614c0df0537567c75f781df7affc091a4a466226 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 15 Nov 2022 20:38:32 +0000 Subject: [PATCH 2/6] clippy --- azalea-client/src/plugins.rs | 10 ++++++---- azalea-physics/src/lib.rs | 11 +++++------ azalea-world/src/entity/attributes.rs | 5 ++--- azalea-world/src/entity/mod.rs | 9 +++++++++ azalea/src/bot.rs | 8 +++----- azalea/src/pathfinder/mod.rs | 2 +- azalea/src/pathfinder/moves.rs | 2 +- azalea/src/pathfinder/mtdstarlite.rs | 2 +- bot/src/main.rs | 5 ++--- 9 files changed, 30 insertions(+), 24 deletions(-) diff --git a/azalea-client/src/plugins.rs b/azalea-client/src/plugins.rs index 1a3aa049..150d5960 100644 --- a/azalea-client/src/plugins.rs +++ b/azalea-client/src/plugins.rs @@ -7,19 +7,21 @@ use std::{ hash::BuildHasherDefault, }; +type U64Hasher = BuildHasherDefault>; + // kind of based on https://docs.rs/http/latest/src/http/extensions.rs.html /// A map of plugin ids to Plugin trait objects. The client stores this so we /// can keep the state for our plugins. /// /// If you're using azalea, you should generate this from the `plugins!` macro. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Plugins { - map: Option, BuildHasherDefault>>>, + map: Option, U64Hasher>>, } impl Plugins { pub fn new() -> Self { - Self { map: None } + Self::default() } pub fn add(&mut self, plugin: T) { @@ -46,7 +48,7 @@ impl IntoIterator for Plugins { fn into_iter(self) -> Self::IntoIter { self.map - .map(|map| map.into_iter().map(|(_, v)| v).collect::>()) + .map(|map| map.into_values().collect::>()) .unwrap_or_default() .into_iter() } diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs index 635a36bc..852874b8 100755 --- a/azalea-physics/src/lib.rs +++ b/azalea-physics/src/lib.rs @@ -122,12 +122,11 @@ impl> HasPhysics for Entity<'_, D> { }; if self.metadata.sprinting { let y_rot = self.y_rot * 0.017453292; - self.delta = self.delta - + Vec3 { - x: (-f32::sin(y_rot) * 0.2) as f64, - y: 0., - z: (f32::cos(y_rot) * 0.2) as f64, - }; + self.delta += Vec3 { + x: (-f32::sin(y_rot) * 0.2) as f64, + y: 0., + z: (f32::cos(y_rot) * 0.2) as f64, + }; } self.has_impulse = true; diff --git a/azalea-world/src/entity/attributes.rs b/azalea-world/src/entity/attributes.rs index 1050615c..f7e9682e 100644 --- a/azalea-world/src/entity/attributes.rs +++ b/azalea-world/src/entity/attributes.rs @@ -40,9 +40,8 @@ impl AttributeInstance { AttributeModifierOperation::MultiplyBase => total += self.base * modifier.amount, _ => {} } - match modifier.operation { - AttributeModifierOperation::MultiplyTotal => total *= 1.0 + modifier.amount, - _ => {} + if let AttributeModifierOperation::MultiplyTotal = modifier.operation { + total *= 1.0 + modifier.amount } } total diff --git a/azalea-world/src/entity/mod.rs b/azalea-world/src/entity/mod.rs index 63147ced..540bfeed 100644 --- a/azalea-world/src/entity/mod.rs +++ b/azalea-world/src/entity/mod.rs @@ -270,10 +270,19 @@ impl EntityData { &self.pos } + /// Convert this &mut self into a (mutable) pointer. + /// + /// # Safety + /// The entity MUST exist while this pointer exists. pub unsafe fn as_ptr(&mut self) -> NonNull { NonNull::new_unchecked(self as *mut EntityData) } + /// Convert this &self into a (mutable) pointer. + /// + /// # Safety + /// The entity MUST exist while this pointer exists. You also must not + /// modify the data inside the pointer. pub unsafe fn as_const_ptr(&self) -> NonNull { // this is cursed NonNull::new_unchecked(self as *const EntityData as *mut EntityData) diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs index 961f093d..0becaa62 100755 --- a/azalea/src/bot.rs +++ b/azalea/src/bot.rs @@ -38,11 +38,9 @@ impl BotTrait for azalea_client::Client { impl crate::Plugin for Plugin { async fn handle(self: Box, event: Event, mut bot: Client) { if let Event::Tick = event { - if *self.state.jumping_once.lock() { - if bot.jumping() { - *self.state.jumping_once.lock() = false; - bot.set_jumping(false); - } + if *self.state.jumping_once.lock() && bot.jumping() { + *self.state.jumping_once.lock() = false; + bot.set_jumping(false); } } } diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index d62b3e05..9fd9fe90 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -77,7 +77,7 @@ impl Trait for azalea_client::Client { let dimension = self.dimension.read(); for possible_move in possible_moves.iter() { edges.push(Edge { - target: possible_move.next_node(&node), + target: possible_move.next_node(node), cost: possible_move.cost(&dimension, node), }); } diff --git a/azalea/src/pathfinder/moves.rs b/azalea/src/pathfinder/moves.rs index ed98b70d..a08d4b80 100644 --- a/azalea/src/pathfinder/moves.rs +++ b/azalea/src/pathfinder/moves.rs @@ -29,7 +29,7 @@ fn is_passable(pos: &BlockPos, dim: &Dimension) -> bool { /// Whether we can stand in this position. Checks if the block below is solid, /// and that the two blocks above that are passable. fn is_standable(pos: &BlockPos, dim: &Dimension) -> bool { - is_block_solid(&pos.down(1), dim) && is_passable(&pos, dim) + is_block_solid(&pos.down(1), dim) && is_passable(pos, dim) } const JUMP_COST: f32 = 0.5; diff --git a/azalea/src/pathfinder/mtdstarlite.rs b/azalea/src/pathfinder/mtdstarlite.rs index 8a40ec37..ff0fe4cc 100644 --- a/azalea/src/pathfinder/mtdstarlite.rs +++ b/azalea/src/pathfinder/mtdstarlite.rs @@ -105,7 +105,7 @@ impl< for n in &known_nodes { *pf.state_mut(n) = NodeState::default(); } - (*pf.state_mut(&start)).rhs = W::default(); + pf.state_mut(&start).rhs = W::default(); pf.open.push(start, pf.calculate_key(&start)); pf diff --git a/bot/src/main.rs b/bot/src/main.rs index f1398062..ce627651 100755 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -58,13 +58,12 @@ async fn handle(bot: Client, event: Event, _state: State) -> anyhow::Result<()> Event::Chat(m) => { println!("{}", m.message().to_ansi(None)); if m.message().to_string() == " goto" { - let target_pos_vec3 = bot + let target_pos_vec3 = *(bot .dimension .read() .entity_by_uuid(&uuid::uuid!("6536bfed869548fd83a1ecd24cf2a0fd")) .unwrap() - .pos() - .clone(); + .pos()); let target_pos: BlockPos = (&target_pos_vec3).into(); // bot.look_at(&target_pos_vec3); bot.goto(BlockPosGoal::from(target_pos)); From 709c5dbc19ffb8c47e001b1d5c14846ee69e7988 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 15 Nov 2022 20:44:33 +0000 Subject: [PATCH 3/6] add Client::metadata --- azalea-client/src/client.rs | 6 ++++++ azalea-world/src/entity/metadata.rs | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 282de48f..2aef1709 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -910,6 +910,12 @@ impl Client { Ok(()) } + + /// Get the player metadata for ourselves. You can use this to get your + /// health, xp score, and other useful information. + pub fn metadata(&self) -> metadata::Player { + self.entity().metadata.clone().into_player().unwrap() + } } impl From> for HandleError { diff --git a/azalea-world/src/entity/metadata.rs b/azalea-world/src/entity/metadata.rs index a031ade2..a74635b3 100644 --- a/azalea-world/src/entity/metadata.rs +++ b/azalea-world/src/entity/metadata.rs @@ -6,6 +6,7 @@ use super::{EntityDataValue, Pose, Rotations, VillagerData}; use azalea_block::BlockState; use azalea_chat::Component; use azalea_core::{BlockPos, Direction, Particle, Slot}; +use enum_as_inner::EnumAsInner; use std::{ collections::VecDeque, ops::{Deref, DerefMut}, @@ -7908,7 +7909,7 @@ impl DerefMut for AbstractTameable { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, EnumAsInner)] pub enum EntityMetadata { Allay(Allay), AreaEffectCloud(AreaEffectCloud), From b9da6f74756abb8daf7253765fdc5f5521381090 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 15 Nov 2022 20:45:03 +0000 Subject: [PATCH 4/6] rephrase that --- azalea-client/src/client.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 2aef1709..296a967b 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -911,8 +911,8 @@ impl Client { Ok(()) } - /// Get the player metadata for ourselves. You can use this to get your - /// health, xp score, and other useful information. + /// Get your player entity's metadata. You can use this to get your health, + /// xp score, and other useful information. pub fn metadata(&self) -> metadata::Player { self.entity().metadata.clone().into_player().unwrap() } From 0d004b72ac22641978c6ef93ca8641eb621e2f48 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Tue, 15 Nov 2022 14:52:26 -0600 Subject: [PATCH 5/6] Rename "dimension" to "world" (#39) * rename "dimension" to "world" * Update mod.rs --- azalea-client/src/client.rs | 78 ++++++++-------- azalea-client/src/movement.rs | 8 +- azalea-client/src/player.rs | 18 ++-- azalea-core/src/position.rs | 8 +- azalea-physics/src/collision/mod.rs | 22 ++--- ...sion_collisions.rs => world_collisions.rs} | 14 +-- azalea-physics/src/lib.rs | 70 +++++++------- azalea-world/src/chunk_storage.rs | 4 +- azalea-world/src/entity/mod.rs | 46 +++++----- azalea-world/src/lib.rs | 17 ++-- azalea/examples/potatobot/main.rs | 2 +- azalea/examples/pvp.rs | 5 +- azalea/src/pathfinder/mod.rs | 4 +- azalea/src/pathfinder/moves.rs | 91 ++++++++++--------- bot/src/main.rs | 2 +- 15 files changed, 197 insertions(+), 192 deletions(-) rename azalea-physics/src/collision/{dimension_collisions.rs => world_collisions.rs} (92%) mode change 100755 => 100644 diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 296a967b..85e5013e 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -29,7 +29,7 @@ use azalea_protocol::{ }; use azalea_world::{ entity::{metadata, Entity, EntityData, EntityMetadata}, - Dimension, + World, }; use log::{debug, error, info, warn}; use parking_lot::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; @@ -87,7 +87,7 @@ pub struct Client { pub read_conn: Arc>>, pub write_conn: Arc>>, pub player: Arc>, - pub dimension: Arc>, + pub world: Arc>, pub physics_state: Arc>, pub client_information: Arc>, /// Plugins are a way for other crates to add custom functionality to the @@ -262,7 +262,7 @@ impl Client { read_conn, write_conn, player: Arc::new(RwLock::new(Player::default())), - dimension: Arc::new(RwLock::new(Dimension::default())), + world: Arc::new(RwLock::new(World::default())), physics_state: Arc::new(Mutex::new(PhysicsState::default())), client_information: Arc::new(RwLock::new(ClientInformation::default())), // The plugins can be modified by the user by replacing the plugins @@ -414,17 +414,17 @@ impl Client { .as_int() .expect("min_y tag is not an int"); - let mut dimension_lock = client.dimension.write(); + let mut world_lock = client.world.write(); // the 16 here is our render distance // i'll make this an actual setting later - *dimension_lock = Dimension::new(16, height, min_y); + *world_lock = World::new(16, height, min_y); let entity = EntityData::new( client.game_profile.uuid, Vec3::default(), EntityMetadata::Player(metadata::Player::default()), ); - dimension_lock.add_entity(p.player_id, entity); + world_lock.add_entity(p.player_id, entity); let mut player_lock = client.player.write(); @@ -497,9 +497,9 @@ impl Client { player_lock.entity_id }; - let mut dimension_lock = client.dimension.write(); + let mut world_lock = client.world.write(); - let mut player_entity = dimension_lock + let mut player_entity = world_lock .entity_mut(player_entity_id) .expect("Player entity doesn't exist"); @@ -553,7 +553,7 @@ impl Client { y: new_pos_y, z: new_pos_z, }; - dimension_lock + world_lock .set_entity_pos(player_entity_id, new_pos) .expect("The player entity should always exist"); @@ -584,7 +584,7 @@ impl Client { ClientboundGamePacket::SetChunkCacheCenter(p) => { debug!("Got chunk cache center packet {:?}", p); client - .dimension + .world .write() .update_view_center(&ChunkPos::new(p.x, p.z)); } @@ -594,7 +594,7 @@ impl Client { // let chunk = Chunk::read_with_world_height(&mut p.chunk_data); // debug("chunk {:?}") if let Err(e) = client - .dimension + .world .write() .replace_with_packet_data(&pos, &mut Cursor::new(&p.chunk_data.data)) { @@ -607,12 +607,12 @@ impl Client { ClientboundGamePacket::AddEntity(p) => { debug!("Got add entity packet {:?}", p); let entity = EntityData::from(p); - client.dimension.write().add_entity(p.id, entity); + client.world.write().add_entity(p.id, entity); } ClientboundGamePacket::SetEntityData(p) => { debug!("Got set entity data packet {:?}", p); - let mut dimension = client.dimension.write(); - if let Some(mut entity) = dimension.entity_mut(p.id) { + let mut world = client.world.write(); + if let Some(mut entity) = world.entity_mut(p.id) { entity.apply_metadata(&p.packed_items.0); } else { warn!("Server sent an entity data packet for an entity id ({}) that we don't know about", p.id); @@ -630,7 +630,7 @@ impl Client { ClientboundGamePacket::AddPlayer(p) => { debug!("Got add player packet {:?}", p); let entity = EntityData::from(p); - client.dimension.write().add_entity(p.id, entity); + client.world.write().add_entity(p.id, entity); } ClientboundGamePacket::InitializeBorder(p) => { debug!("Got initialize border packet {:?}", p); @@ -651,9 +651,9 @@ impl Client { debug!("Got set experience packet {:?}", p); } ClientboundGamePacket::TeleportEntity(p) => { - let mut dimension_lock = client.dimension.write(); + let mut world_lock = client.world.write(); - dimension_lock + world_lock .set_entity_pos( p.id, Vec3 { @@ -671,16 +671,16 @@ impl Client { // debug!("Got rotate head packet {:?}", p); } ClientboundGamePacket::MoveEntityPos(p) => { - let mut dimension_lock = client.dimension.write(); + let mut world_lock = client.world.write(); - dimension_lock + world_lock .move_entity_with_delta(p.entity_id, &p.delta) .map_err(|e| HandleError::Other(e.into()))?; } ClientboundGamePacket::MoveEntityPosRot(p) => { - let mut dimension_lock = client.dimension.write(); + let mut world_lock = client.world.write(); - dimension_lock + world_lock .move_entity_with_delta(p.entity_id, &p.delta) .map_err(|e| HandleError::Other(e.into()))?; } @@ -713,17 +713,17 @@ impl Client { } ClientboundGamePacket::BlockUpdate(p) => { debug!("Got block update packet {:?}", p); - let mut dimension = client.dimension.write(); - dimension.set_block_state(&p.pos, p.block_state); + let mut world = client.world.write(); + world.set_block_state(&p.pos, p.block_state); } ClientboundGamePacket::Animate(p) => { debug!("Got animate packet {:?}", p); } ClientboundGamePacket::SectionBlocksUpdate(p) => { debug!("Got section blocks update packet {:?}", p); - let mut dimension = client.dimension.write(); + let mut world = client.world.write(); for state in &p.states { - dimension.set_block_state(&(p.section_pos + state.pos.clone()), state.state); + world.set_block_state(&(p.section_pos + state.pos.clone()), state.state); } } ClientboundGamePacket::GameEvent(p) => { @@ -819,16 +819,16 @@ impl Client { async fn game_tick(client: &mut Client, tx: &UnboundedSender) { // return if there's no chunk at the player's position { - let dimension_lock = client.dimension.write(); + let world_lock = client.world.write(); let player_lock = client.player.write(); - let player_entity = player_lock.entity(&dimension_lock); + let player_entity = player_lock.entity(&world_lock); let player_entity = if let Some(player_entity) = player_entity { player_entity } else { return; }; let player_chunk_pos: ChunkPos = player_entity.pos().into(); - if dimension_lock[&player_chunk_pos].is_none() { + if world_lock[&player_chunk_pos].is_none() { return; } } @@ -846,43 +846,43 @@ impl Client { } /// Returns the entity associated to the player. - pub fn entity_mut(&self) -> Entity> { + pub fn entity_mut(&self) -> Entity> { let entity_id = { let player_lock = self.player.write(); player_lock.entity_id }; - let mut dimension = self.dimension.write(); + let mut world = self.world.write(); - let entity_data = dimension + let entity_data = world .entity_storage .get_mut_by_id(entity_id) .expect("Player entity should exist"); let entity_ptr = unsafe { entity_data.as_ptr() }; - Entity::new(dimension, entity_id, entity_ptr) + Entity::new(world, entity_id, entity_ptr) } /// Returns the entity associated to the player. - pub fn entity(&self) -> Entity> { + pub fn entity(&self) -> Entity> { let entity_id = { let player_lock = self.player.read(); player_lock.entity_id }; - let dimension = self.dimension.read(); + let world = self.world.read(); - let entity_data = dimension + let entity_data = world .entity_storage .get_by_id(entity_id) - .expect("Player entity should be in the given dimension"); + .expect("Player entity should be in the given world"); let entity_ptr = unsafe { entity_data.as_const_ptr() }; - Entity::new(dimension, entity_id, entity_ptr) + Entity::new(world, entity_id, entity_ptr) } /// Returns whether we have a received the login packet yet. pub fn logged_in(&self) -> bool { - let dimension = self.dimension.read(); + let world = self.world.read(); let player = self.player.write(); - player.entity(&dimension).is_some() + player.entity(&world).is_some() } /// Tell the server we changed our game options (i.e. render distance, main hand). diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs index 145513c0..d33b4b4a 100755 --- a/azalea-client/src/movement.rs +++ b/azalea-client/src/movement.rs @@ -154,19 +154,19 @@ impl Client { // Set our current position to the provided Vec3, potentially clipping through blocks. pub async fn set_pos(&mut self, new_pos: Vec3) -> Result<(), MovePlayerError> { let player_lock = self.player.write(); - let mut dimension_lock = self.dimension.write(); + let mut world_lock = self.world.write(); - dimension_lock.set_entity_pos(player_lock.entity_id, new_pos)?; + world_lock.set_entity_pos(player_lock.entity_id, new_pos)?; Ok(()) } pub async fn move_entity(&mut self, movement: &Vec3) -> Result<(), MovePlayerError> { - let mut dimension_lock = self.dimension.write(); + let mut world_lock = self.world.write(); let player = self.player.write(); let mut entity = player - .entity_mut(&mut dimension_lock) + .entity_mut(&mut world_lock) .ok_or(MovePlayerError::PlayerNotInWorld)?; log::trace!( "move entity bounding box: {} {:?}", diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs index ea6125ad..a355831b 100755 --- a/azalea-client/src/player.rs +++ b/azalea-client/src/player.rs @@ -1,13 +1,13 @@ use azalea_world::entity::Entity; -use azalea_world::Dimension; +use azalea_world::World; use uuid::Uuid; -/// Something that has a dimension associated to it. Usually, this is a `Client`. -pub trait DimensionHaver { - fn dimension(&self) -> &Dimension; +/// Something that has a world associated to it. Usually, this is a `Client`. +pub trait WorldHaver { + fn world(&self) -> &World; } -/// A player in the dimension or tab list. +/// A player in the world or tab list. #[derive(Default, Debug)] pub struct Player { /// The player's uuid. @@ -18,13 +18,13 @@ pub struct Player { impl Player { /// Get a reference to the entity of the player in the world. - pub fn entity<'d>(&'d self, dimension: &'d Dimension) -> Option> { - dimension.entity(self.entity_id) + pub fn entity<'d>(&'d self, world: &'d World) -> Option> { + world.entity(self.entity_id) } /// Get a mutable reference to the entity of the player in the world. - pub fn entity_mut<'d>(&'d self, dimension: &'d mut Dimension) -> Option { - dimension.entity_mut(self.entity_id) + pub fn entity_mut<'d>(&'d self, world: &'d mut World) -> Option { + world.entity_mut(self.entity_id) } pub fn set_uuid(&mut self, uuid: Uuid) { diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index 61368b28..6c18d147 100755 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -197,12 +197,12 @@ impl Add for ChunkSectionPos { } } -/// A block pos with an attached dimension +/// A block pos with an attached world #[derive(Debug, Clone)] pub struct GlobalPos { pub pos: BlockPos, // this is actually a ResourceKey in Minecraft, but i don't think it matters? - pub dimension: ResourceLocation, + pub world: ResourceLocation, } impl From<&BlockPos> for ChunkPos { @@ -297,7 +297,7 @@ impl McBufReadable for BlockPos { impl McBufReadable for GlobalPos { fn read_from(buf: &mut Cursor<&[u8]>) -> Result { Ok(GlobalPos { - dimension: ResourceLocation::read_from(buf)?, + world: ResourceLocation::read_from(buf)?, pos: BlockPos::read_from(buf)?, }) } @@ -326,7 +326,7 @@ impl McBufWritable for BlockPos { impl McBufWritable for GlobalPos { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { - ResourceLocation::write_into(&self.dimension, buf)?; + ResourceLocation::write_into(&self.world, buf)?; BlockPos::write_into(&self.pos, buf)?; Ok(()) diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs index d5502f3d..aa585aa8 100755 --- a/azalea-physics/src/collision/mod.rs +++ b/azalea-physics/src/collision/mod.rs @@ -1,18 +1,18 @@ mod blocks; -mod dimension_collisions; mod discrete_voxel_shape; mod mergers; mod shape; +mod world_collisions; use std::ops::DerefMut; use azalea_core::{Axis, Vec3, AABB, EPSILON}; use azalea_world::entity::{Entity, EntityData}; -use azalea_world::{Dimension, MoveEntityError}; +use azalea_world::{MoveEntityError, World}; pub use blocks::BlockWithShape; -use dimension_collisions::CollisionGetter; pub use discrete_voxel_shape::*; pub use shape::*; +use world_collisions::CollisionGetter; pub enum MoverType { Own, @@ -34,7 +34,7 @@ pub trait MovableEntity { ) -> Result<(), MoveEntityError>; } -impl HasCollision for Dimension { +impl HasCollision for World { // private Vec3 collide(Vec3 var1) { // AABB var2 = this.getBoundingBox(); // List var3 = this.level.getEntityCollisions(this, var2.expandTowards(var1)); @@ -63,7 +63,7 @@ impl HasCollision for Dimension { fn collide(&self, movement: &Vec3, entity: &EntityData) -> Vec3 { let entity_bounding_box = entity.bounding_box; // TODO: get_entity_collisions - // let entity_collisions = dimension.get_entity_collisions(self, entity_bounding_box.expand_towards(movement)); + // let entity_collisions = world.get_entity_collisions(self, entity_bounding_box.expand_towards(movement)); let entity_collisions = Vec::new(); if movement.length_sqr() == 0.0 { *movement @@ -83,7 +83,7 @@ impl HasCollision for Dimension { } } -impl> MovableEntity for Entity<'_, D> { +impl> MovableEntity for Entity<'_, D> { /// Move an entity by a given delta, checking for collisions. fn move_colliding( &mut self, @@ -111,7 +111,7 @@ impl> MovableEntity for Entity<'_, D> { // movement = this.maybeBackOffFromEdge(movement, moverType); - let collide_result = { self.dimension.collide(movement, self) }; + let collide_result = { self.world.collide(movement, self) }; let move_distance = collide_result.length_sqr(); @@ -127,7 +127,7 @@ impl> MovableEntity for Entity<'_, D> { } }; - self.dimension.set_entity_pos(self.id, new_pos)?; + self.world.set_entity_pos(self.id, new_pos)?; } let x_collision = movement.x != collide_result.x; @@ -141,7 +141,7 @@ impl> MovableEntity for Entity<'_, D> { let _block_pos_below = self.on_pos_legacy(); // let _block_state_below = self - // .dimension + // .world // .get_block_state(&block_pos_below) // .expect("Couldn't get block state below"); @@ -198,7 +198,7 @@ fn collide_bounding_box( entity: Option<&EntityData>, movement: &Vec3, entity_bounding_box: &AABB, - dimension: &Dimension, + world: &World, entity_collisions: Vec, ) -> Vec3 { let mut collision_boxes: Vec = Vec::with_capacity(entity_collisions.len() + 1); @@ -210,7 +210,7 @@ fn collide_bounding_box( // TODO: world border let block_collisions = - dimension.get_block_collisions(entity, entity_bounding_box.expand_towards(movement)); + world.get_block_collisions(entity, entity_bounding_box.expand_towards(movement)); let block_collisions = block_collisions.collect::>(); collision_boxes.extend(block_collisions); collide_with_shapes(movement, *entity_bounding_box, &collision_boxes) diff --git a/azalea-physics/src/collision/dimension_collisions.rs b/azalea-physics/src/collision/world_collisions.rs old mode 100755 new mode 100644 similarity index 92% rename from azalea-physics/src/collision/dimension_collisions.rs rename to azalea-physics/src/collision/world_collisions.rs index fd4e5141..65f7f5bb --- a/azalea-physics/src/collision/dimension_collisions.rs +++ b/azalea-physics/src/collision/world_collisions.rs @@ -2,7 +2,7 @@ use crate::collision::{BlockWithShape, VoxelShape, AABB}; use azalea_block::BlockState; use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType, EPSILON}; use azalea_world::entity::EntityData; -use azalea_world::{Chunk, Dimension}; +use azalea_world::{Chunk, World}; use parking_lot::Mutex; use std::sync::Arc; @@ -16,7 +16,7 @@ pub trait CollisionGetter { ) -> BlockCollisions<'a>; } -impl CollisionGetter for Dimension { +impl CollisionGetter for World { fn get_block_collisions<'a>( &'a self, entity: Option<&EntityData>, @@ -27,7 +27,7 @@ impl CollisionGetter for Dimension { } pub struct BlockCollisions<'a> { - pub dimension: &'a Dimension, + pub world: &'a World, // context: CollisionContext, pub aabb: AABB, pub entity_shape: VoxelShape, @@ -37,7 +37,7 @@ pub struct BlockCollisions<'a> { impl<'a> BlockCollisions<'a> { // TODO: the entity is stored in the context - pub fn new(dimension: &'a Dimension, _entity: Option<&EntityData>, aabb: AABB) -> Self { + pub fn new(world: &'a World, _entity: Option<&EntityData>, aabb: AABB) -> Self { let origin_x = (aabb.min_x - EPSILON) as i32 - 1; let origin_y = (aabb.min_y - EPSILON) as i32 - 1; let origin_z = (aabb.min_z - EPSILON) as i32 - 1; @@ -49,7 +49,7 @@ impl<'a> BlockCollisions<'a> { let cursor = Cursor3d::new(origin_x, origin_y, origin_z, end_x, end_y, end_z); Self { - dimension, + world, aabb, entity_shape: VoxelShape::from(aabb), cursor, @@ -75,7 +75,7 @@ impl<'a> BlockCollisions<'a> { // return var7; // } - self.dimension[&chunk_pos].as_ref() + self.world[&chunk_pos].as_ref() } } @@ -97,7 +97,7 @@ impl<'a> Iterator for BlockCollisions<'a> { let pos = item.pos; let block_state: BlockState = chunk .lock() - .get(&(&pos).into(), self.dimension.min_y()) + .get(&(&pos).into(), self.world.min_y()) .unwrap_or(BlockState::Air); // TODO: continue if self.only_suffocating_blocks and the block is not suffocating diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs index 852874b8..2295e6f2 100755 --- a/azalea-physics/src/lib.rs +++ b/azalea-physics/src/lib.rs @@ -8,7 +8,7 @@ use azalea_block::{Block, BlockState}; use azalea_core::{BlockPos, Vec3}; use azalea_world::{ entity::{Entity, EntityData}, - Dimension, + World, }; use collision::{MovableEntity, MoverType}; @@ -19,7 +19,7 @@ pub trait HasPhysics { fn jump_from_ground(&mut self); } -impl> HasPhysics for Entity<'_, D> { +impl> HasPhysics for Entity<'_, D> { /// Move the entity with the given acceleration while handling friction, /// gravity, collisions, and some other stuff. fn travel(&mut self, acceleration: &Vec3) { @@ -40,7 +40,7 @@ impl> HasPhysics for Entity<'_, D> { let block_pos_below = get_block_pos_below_that_affects_movement(self); let block_state_below = self - .dimension + .world .get_block_state(&block_pos_below) .unwrap_or(BlockState::Air); let block_below: Box = block_state_below.into(); @@ -142,7 +142,7 @@ fn get_block_pos_below_that_affects_movement(entity: &EntityData) -> BlockPos { ) } -fn handle_relative_friction_and_calculate_movement>( +fn handle_relative_friction_and_calculate_movement>( entity: &mut Entity, acceleration: &Vec3, block_friction: f32, @@ -181,10 +181,10 @@ fn get_friction_influenced_speed(entity: &EntityData, friction: f32) -> f32 { /// Returns the what the entity's jump should be multiplied by based on the /// block they're standing on. -fn block_jump_factor>(entity: &Entity) -> f32 { - let block_at_pos = entity.dimension.get_block_state(&entity.pos().into()); +fn block_jump_factor>(entity: &Entity) -> f32 { + let block_at_pos = entity.world.get_block_state(&entity.pos().into()); let block_below = entity - .dimension + .world .get_block_state(&get_block_pos_below_that_affects_movement(entity)); let block_at_pos_jump_factor = if let Some(block) = block_at_pos { @@ -209,11 +209,11 @@ fn block_jump_factor>(entity: &Entity) -> f32 // public double getJumpBoostPower() { // return this.hasEffect(MobEffects.JUMP) ? (double)(0.1F * (float)(this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D; // } -fn jump_power>(entity: &Entity) -> f32 { +fn jump_power>(entity: &Entity) -> f32 { 0.42 * block_jump_factor(entity) } -fn jump_boost_power>(_entity: &Entity) -> f64 { +fn jump_boost_power>(_entity: &Entity) -> f64 { // TODO: potion effects // if let Some(effects) = entity.effects() { // if let Some(jump_effect) = effects.get(&Effect::Jump) { @@ -231,14 +231,14 @@ fn jump_boost_power>(_entity: &Entity) -> f64 mod tests { use super::*; use azalea_core::ChunkPos; - use azalea_world::{Chunk, Dimension}; + use azalea_world::{Chunk, World}; use uuid::Uuid; #[test] fn test_gravity() { - let mut dim = Dimension::default(); + let mut world = World::default(); - dim.add_entity( + world.add_entity( 0, EntityData::new( Uuid::from_u128(0), @@ -249,7 +249,7 @@ mod tests { }, ), ); - let mut entity = dim.entity_mut(0).unwrap(); + let mut entity = world.entity_mut(0).unwrap(); // y should start at 70 assert_eq!(entity.pos().y, 70.); entity.ai_step(); @@ -266,10 +266,11 @@ mod tests { } #[test] fn test_collision() { - let mut dim = Dimension::default(); - dim.set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) + let mut world = World::default(); + world + .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); - dim.add_entity( + world.add_entity( 0, EntityData::new( Uuid::from_u128(0), @@ -280,12 +281,12 @@ mod tests { }, ), ); - let block_state = dim.set_block_state(&BlockPos { x: 0, y: 69, z: 0 }, BlockState::Stone); + let block_state = world.set_block_state(&BlockPos { x: 0, y: 69, z: 0 }, BlockState::Stone); assert!( block_state.is_some(), "Block state should exist, if this fails that means the chunk wasn't loaded and the block didn't get placed" ); - let mut entity = dim.entity_mut(0).unwrap(); + let mut entity = world.entity_mut(0).unwrap(); entity.ai_step(); // delta will change, but it won't move until next tick assert_eq!(entity.pos().y, 70.); @@ -297,10 +298,11 @@ mod tests { #[test] fn test_slab_collision() { - let mut dim = Dimension::default(); - dim.set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) + let mut world = World::default(); + world + .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); - dim.add_entity( + world.add_entity( 0, EntityData::new( Uuid::from_u128(0), @@ -311,7 +313,7 @@ mod tests { }, ), ); - let block_state = dim.set_block_state( + let block_state = world.set_block_state( &BlockPos { x: 0, y: 69, z: 0 }, BlockState::StoneSlab_BottomFalse, ); @@ -319,7 +321,7 @@ mod tests { block_state.is_some(), "Block state should exist, if this fails that means the chunk wasn't loaded and the block didn't get placed" ); - let mut entity = dim.entity_mut(0).unwrap(); + let mut entity = world.entity_mut(0).unwrap(); // do a few steps so we fall on the slab for _ in 0..20 { entity.ai_step(); @@ -329,10 +331,11 @@ mod tests { #[test] fn test_top_slab_collision() { - let mut dim = Dimension::default(); - dim.set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) + let mut world = World::default(); + world + .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); - dim.add_entity( + world.add_entity( 0, EntityData::new( Uuid::from_u128(0), @@ -343,7 +346,7 @@ mod tests { }, ), ); - let block_state = dim.set_block_state( + let block_state = world.set_block_state( &BlockPos { x: 0, y: 69, z: 0 }, BlockState::StoneSlab_TopFalse, ); @@ -351,7 +354,7 @@ mod tests { block_state.is_some(), "Block state should exist, if this fails that means the chunk wasn't loaded and the block didn't get placed" ); - let mut entity = dim.entity_mut(0).unwrap(); + let mut entity = world.entity_mut(0).unwrap(); // do a few steps so we fall on the slab for _ in 0..20 { entity.ai_step(); @@ -361,10 +364,11 @@ mod tests { #[test] fn test_weird_wall_collision() { - let mut dim = Dimension::default(); - dim.set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) + let mut world = World::default(); + world + .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); - dim.add_entity( + world.add_entity( 0, EntityData::new( Uuid::from_u128(0), @@ -375,7 +379,7 @@ mod tests { }, ), ); - let block_state = dim.set_block_state( + let block_state = world.set_block_state( &BlockPos { x: 0, y: 69, z: 0 }, BlockState::CobblestoneWall_LowLowLowFalseFalseLow, ); @@ -383,7 +387,7 @@ mod tests { block_state.is_some(), "Block state should exist, if this fails that means the chunk wasn't loaded and the block didn't get placed" ); - let mut entity = dim.entity_mut(0).unwrap(); + let mut entity = world.entity_mut(0).unwrap(); // do a few steps so we fall on the slab for _ in 0..20 { entity.ai_step(); diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs index 85f0ebb3..a03cbe7b 100755 --- a/azalea-world/src/chunk_storage.rs +++ b/azalea-world/src/chunk_storage.rs @@ -1,6 +1,6 @@ use crate::palette::PalettedContainer; use crate::palette::PalettedContainerType; -use crate::Dimension; +use crate::World; use azalea_block::BlockState; use azalea_buf::BufReadError; use azalea_buf::{McBufReadable, McBufWritable}; @@ -143,7 +143,7 @@ impl IndexMut<&ChunkPos> for ChunkStorage { impl Chunk { pub fn read_with_dimension( buf: &mut Cursor<&[u8]>, - data: &Dimension, + data: &World, ) -> Result { Self::read_with_dimension_height(buf, data.height()) } diff --git a/azalea-world/src/entity/mod.rs b/azalea-world/src/entity/mod.rs index 540bfeed..4611f215 100644 --- a/azalea-world/src/entity/mod.rs +++ b/azalea-world/src/entity/mod.rs @@ -5,7 +5,7 @@ pub mod metadata; use self::attributes::{AttributeInstance, AttributeModifiers}; pub use self::metadata::EntityMetadata; -use crate::Dimension; +use crate::World; use azalea_block::BlockState; use azalea_core::{BlockPos, Vec3, AABB}; pub use data::*; @@ -15,22 +15,22 @@ use std::ops::{Deref, DerefMut}; use std::ptr::NonNull; use uuid::Uuid; -/// A reference to an entity in a dimension. +/// A reference to an entity in a world. #[derive(Debug)] -pub struct Entity<'d, D = &'d mut Dimension> { - /// The dimension this entity is in. - pub dimension: D, +pub struct Entity<'d, D = &'d mut World> { + /// The world this entity is in. + pub world: D, /// The incrementing numerical id of the entity. pub id: u32, pub data: NonNull, _marker: PhantomData<&'d ()>, } -impl<'d, D: Deref> Entity<'d, D> { - pub fn new(dimension: D, id: u32, data: NonNull) -> Self { +impl<'d, D: Deref> Entity<'d, D> { + pub fn new(world: D, id: u32, data: NonNull) -> Self { // TODO: have this be based on the entity type Self { - dimension, + world, id, data, _marker: PhantomData, @@ -38,12 +38,12 @@ impl<'d, D: Deref> Entity<'d, D> { } } -impl<'d, D: DerefMut> Entity<'d, D> { +impl<'d, D: DerefMut> Entity<'d, D> { /// Sets the position of the entity. This doesn't update the cache in /// azalea-world, and should only be used within azalea-world! /// /// # Safety - /// Cached position in the dimension must be updated. + /// Cached position in the world must be updated. pub unsafe fn move_unchecked(&mut self, new_pos: Vec3) { self.pos = new_pos; let bounding_box = self.make_bounding_box(); @@ -94,7 +94,7 @@ impl<'d, D: DerefMut> Entity<'d, D> { } } -impl<'d, D: Deref> Entity<'d, D> { +impl<'d, D: Deref> Entity<'d, D> { #[inline] pub fn pos(&self) -> &Vec3 { &self.pos @@ -129,10 +129,10 @@ impl<'d, D: Deref> Entity<'d, D> { // TODO: check if block below is a fence, wall, or fence gate let block_pos = pos.down(1); - let block_state = self.dimension.get_block_state(&block_pos); + let block_state = self.world.get_block_state(&block_pos); if block_state == Some(BlockState::Air) { let block_pos_below = block_pos.down(1); - let block_state_below = self.dimension.get_block_state(&block_pos_below); + let block_state_below = self.world.get_block_state(&block_pos_below); if let Some(_block_state_below) = block_state_below { // if block_state_below.is_fence() // || block_state_below.is_wall() @@ -149,13 +149,13 @@ impl<'d, D: Deref> Entity<'d, D> { // impl< // 'd, -// D: DerefMut + Deref, -// D2: Deref, +// D: DerefMut + Deref, +// D2: Deref, // > From> for Entity<'d, D2> // { // fn from(entity: Entity<'d, D>) -> Entity<'d, D> { // Entity { -// dimension: entity.dimension, +// world: entity.world, // id: entity.id, // data: entity.data, // _marker: PhantomData, @@ -163,13 +163,13 @@ impl<'d, D: Deref> Entity<'d, D> { // } // } -impl> DerefMut for Entity<'_, D> { +impl> DerefMut for Entity<'_, D> { fn deref_mut(&mut self) -> &mut Self::Target { unsafe { self.data.as_mut() } } } -impl> Deref for Entity<'_, D> { +impl> Deref for Entity<'_, D> { type Target = EntityData; fn deref(&self) -> &Self::Target { @@ -181,7 +181,7 @@ impl> Deref for Entity<'_, D> { pub struct EntityData { pub uuid: Uuid, /// The position of the entity right now. - /// This can be changde with unsafe_move, but the correct way is with dimension.move_entity + /// This can be changde with unsafe_move, but the correct way is with world.move_entity pos: Vec3, /// The position of the entity last tick. pub last_pos: Vec3, @@ -264,7 +264,7 @@ impl EntityData { } } - /// Get the position of the entity in the dimension. + /// Get the position of the entity in the world. #[inline] pub fn pos(&self) -> &Vec3 { &self.pos @@ -295,9 +295,9 @@ mod tests { #[test] fn from_mut_entity_to_ref_entity() { - let mut dim = Dimension::default(); + let mut world = World::default(); let uuid = Uuid::from_u128(100); - dim.add_entity( + world.add_entity( 0, EntityData::new( uuid, @@ -305,7 +305,7 @@ mod tests { EntityMetadata::Player(metadata::Player::default()), ), ); - let entity: Entity = dim.entity_mut(0).unwrap(); + let entity: Entity = world.entity_mut(0).unwrap(); let entity_ref = Entity::from(entity); assert_eq!(entity_ref.uuid, uuid); } diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 30e09fe9..a802f4c3 100755 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -22,10 +22,9 @@ use std::{ use thiserror::Error; use uuid::Uuid; -/// A dimension is a collection of chunks and entities. -/// Minecraft calls these "Levels", Fabric calls them "Worlds", Minestom calls them "Instances". +/// A world is a collection of chunks and entities. They're called "levels" in Minecraft's source code. #[derive(Debug, Default)] -pub struct Dimension { +pub struct World { pub chunk_storage: ChunkStorage, pub entity_storage: EntityStorage, } @@ -36,9 +35,9 @@ pub enum MoveEntityError { EntityDoesNotExist, } -impl Dimension { +impl World { pub fn new(chunk_radius: u32, height: u32, min_y: i32) -> Self { - Dimension { + World { chunk_storage: ChunkStorage::new(chunk_radius, height, min_y), entity_storage: EntityStorage::new(), } @@ -127,13 +126,13 @@ impl Dimension { self.entity_storage.get_mut_by_id(id) } - pub fn entity(&self, id: u32) -> Option> { + pub fn entity(&self, id: u32) -> Option> { let entity_data = self.entity_storage.get_by_id(id)?; let entity_ptr = unsafe { entity_data.as_const_ptr() }; Some(Entity::new(self, id, entity_ptr)) } - pub fn entity_mut(&mut self, id: u32) -> Option> { + pub fn entity_mut(&mut self, id: u32) -> Option> { let entity_data = self.entity_storage.get_mut_by_id(id)?; let entity_ptr = unsafe { entity_data.as_ptr() }; Some(Entity::new(self, id, entity_ptr)) @@ -157,14 +156,14 @@ impl Dimension { } } -impl Index<&ChunkPos> for Dimension { +impl Index<&ChunkPos> for World { type Output = Option>>; fn index(&self, pos: &ChunkPos) -> &Self::Output { &self.chunk_storage[pos] } } -impl IndexMut<&ChunkPos> for Dimension { +impl IndexMut<&ChunkPos> for World { fn index_mut<'a>(&'a mut self, pos: &ChunkPos) -> &'a mut Self::Output { &mut self.chunk_storage[pos] } diff --git a/azalea/examples/potatobot/main.rs b/azalea/examples/potatobot/main.rs index 66ddfcc0..e585c41d 100755 --- a/azalea/examples/potatobot/main.rs +++ b/azalea/examples/potatobot/main.rs @@ -49,7 +49,7 @@ async fn deposit(bot: &mut Client, state: State) -> anyhow::Result<()> { bot.goto(Vec3::new(0, 70, 0)).await?; let chest = bot - .open_container(&bot.dimension.block_at(BlockPos::new(0, 70, 0))) + .open_container(&bot.world.block_at(BlockPos::new(0, 70, 0))) .await .unwrap(); diff --git a/azalea/examples/pvp.rs b/azalea/examples/pvp.rs index 435c335c..87d83c6d 100755 --- a/azalea/examples/pvp.rs +++ b/azalea/examples/pvp.rs @@ -36,10 +36,7 @@ async fn swarm_handle(swarm: Swarm, event: Event, state: State) { match event { Event::Tick => { // choose an arbitrary player within render distance to target - if let Some(target) = swarm - .dimension - .find_one_entity(|e| e.id == "minecraft:player") - { + if let Some(target) = swarm.world.find_one_entity(|e| e.id == "minecraft:player") { for bot in swarm { bot.tick_goto_goal(pathfinder::Goals::Reach(target.bounding_box)); // if target.bounding_box.distance(bot.eyes) < bot.reach_distance() { diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index 9fd9fe90..6f31512e 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -74,11 +74,11 @@ impl Trait for azalea_client::Client { let successors = |node: &Node| { let mut edges = Vec::new(); - let dimension = self.dimension.read(); + let world = self.world.read(); for possible_move in possible_moves.iter() { edges.push(Edge { target: possible_move.next_node(node), - cost: possible_move.cost(&dimension, node), + cost: possible_move.cost(&world, node), }); } edges diff --git a/azalea/src/pathfinder/moves.rs b/azalea/src/pathfinder/moves.rs index a08d4b80..63e24412 100644 --- a/azalea/src/pathfinder/moves.rs +++ b/azalea/src/pathfinder/moves.rs @@ -1,11 +1,11 @@ use super::{Node, VerticalVel}; use azalea_core::{BlockPos, CardinalDirection}; use azalea_physics::collision::{self, BlockWithShape}; -use azalea_world::Dimension; +use azalea_world::World; /// whether this block is passable -fn is_block_passable(pos: &BlockPos, dim: &Dimension) -> bool { - if let Some(block) = dim.get_block_state(pos) { +fn is_block_passable(pos: &BlockPos, world: &World) -> bool { + if let Some(block) = world.get_block_state(pos) { block.shape() == &collision::empty_shape() } else { false @@ -13,8 +13,8 @@ fn is_block_passable(pos: &BlockPos, dim: &Dimension) -> bool { } /// whether this block has a solid hitbox (i.e. we can stand on it) -fn is_block_solid(pos: &BlockPos, dim: &Dimension) -> bool { - if let Some(block) = dim.get_block_state(pos) { +fn is_block_solid(pos: &BlockPos, world: &World) -> bool { + if let Some(block) = world.get_block_state(pos) { block.shape() == &collision::block_shape() } else { false @@ -22,21 +22,22 @@ fn is_block_solid(pos: &BlockPos, dim: &Dimension) -> bool { } /// Whether this block and the block above are passable -fn is_passable(pos: &BlockPos, dim: &Dimension) -> bool { - is_block_passable(pos, dim) && is_block_passable(&pos.up(1), dim) +fn is_passable(pos: &BlockPos, world: &World) -> bool { + is_block_passable(pos, world) && is_block_passable(&pos.up(1), world) } /// Whether we can stand in this position. Checks if the block below is solid, /// and that the two blocks above that are passable. -fn is_standable(pos: &BlockPos, dim: &Dimension) -> bool { - is_block_solid(&pos.down(1), dim) && is_passable(pos, dim) + +fn is_standable(pos: &BlockPos, world: &World) -> bool { + is_block_solid(&pos.down(1), world) && is_passable(pos, world) } const JUMP_COST: f32 = 0.5; const WALK_ONE_BLOCK_COST: f32 = 1.0; pub trait Move { - fn cost(&self, dim: &Dimension, node: &Node) -> f32; + fn cost(&self, world: &World, node: &Node) -> f32; /// Returns by how much the entity's position should be changed when this move is executed. fn offset(&self) -> BlockPos; fn next_node(&self, node: &Node) -> Node { @@ -49,8 +50,9 @@ pub trait Move { pub struct ForwardMove(pub CardinalDirection); impl Move for ForwardMove { - fn cost(&self, dim: &Dimension, node: &Node) -> f32 { - if is_standable(&(node.pos + self.offset()), dim) && node.vertical_vel == VerticalVel::None + fn cost(&self, world: &World, node: &Node) -> f32 { + if is_standable(&(node.pos + self.offset()), world) + && node.vertical_vel == VerticalVel::None { WALK_ONE_BLOCK_COST } else { @@ -64,10 +66,10 @@ impl Move for ForwardMove { pub struct AscendMove(pub CardinalDirection); impl Move for AscendMove { - fn cost(&self, dim: &Dimension, node: &Node) -> f32 { + fn cost(&self, world: &World, node: &Node) -> f32 { if node.vertical_vel == VerticalVel::None - && is_block_passable(&node.pos.up(2), dim) - && is_standable(&(node.pos + self.offset()), dim) + && is_block_passable(&node.pos.up(2), world) + && is_standable(&(node.pos + self.offset()), world) { WALK_ONE_BLOCK_COST + JUMP_COST } else { @@ -86,11 +88,11 @@ impl Move for AscendMove { } pub struct DescendMove(pub CardinalDirection); impl Move for DescendMove { - fn cost(&self, dim: &Dimension, node: &Node) -> f32 { + fn cost(&self, world: &World, node: &Node) -> f32 { // check whether 3 blocks vertically forward are passable if node.vertical_vel == VerticalVel::None - && is_standable(&(node.pos + self.offset()), dim) - && is_block_passable(&(node.pos + self.offset().up(2)), dim) + && is_standable(&(node.pos + self.offset()), world) + && is_block_passable(&(node.pos + self.offset().up(2)), world) { WALK_ONE_BLOCK_COST } else { @@ -109,24 +111,24 @@ impl Move for DescendMove { } pub struct DiagonalMove(pub CardinalDirection); impl Move for DiagonalMove { - fn cost(&self, dim: &Dimension, node: &Node) -> f32 { + fn cost(&self, world: &World, node: &Node) -> f32 { if node.vertical_vel != VerticalVel::None { return f32::INFINITY; } if !is_passable( &BlockPos::new(node.pos.x + self.0.x(), node.pos.y, node.pos.z + self.0.z()), - dim, + world, ) && !is_passable( &BlockPos::new( node.pos.x + self.0.right().x(), node.pos.y, node.pos.z + self.0.right().z(), ), - dim, + world, ) { return f32::INFINITY; } - if !is_standable(&(node.pos + self.offset()), dim) { + if !is_standable(&(node.pos + self.offset()), world) { return f32::INFINITY; } WALK_ONE_BLOCK_COST * 1.4 @@ -152,40 +154,43 @@ mod tests { #[test] fn test_is_passable() { - let mut dim = Dimension::default(); - dim.set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) + let mut world = World::default(); + world + .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); - dim.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); - dim.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); + world.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); + world.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); - assert_eq!(is_block_passable(&BlockPos::new(0, 0, 0), &dim), false); - assert_eq!(is_block_passable(&BlockPos::new(0, 1, 0), &dim), true); + assert_eq!(is_block_passable(&BlockPos::new(0, 0, 0), &world), false); + assert_eq!(is_block_passable(&BlockPos::new(0, 1, 0), &world), true); } #[test] fn test_is_solid() { - let mut dim = Dimension::default(); - dim.set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) + let mut world = World::default(); + world + .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); - dim.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); - dim.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); + world.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); + world.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); - assert_eq!(is_block_solid(&BlockPos::new(0, 0, 0), &dim), true); - assert_eq!(is_block_solid(&BlockPos::new(0, 1, 0), &dim), false); + assert_eq!(is_block_solid(&BlockPos::new(0, 0, 0), &world), true); + assert_eq!(is_block_solid(&BlockPos::new(0, 1, 0), &world), false); } #[test] fn test_is_standable() { - let mut dim = Dimension::default(); - dim.set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) + let mut world = World::default(); + world + .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); - dim.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); - dim.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); - dim.set_block_state(&BlockPos::new(0, 2, 0), BlockState::Air); - dim.set_block_state(&BlockPos::new(0, 3, 0), BlockState::Air); + world.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); + world.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); + world.set_block_state(&BlockPos::new(0, 2, 0), BlockState::Air); + world.set_block_state(&BlockPos::new(0, 3, 0), BlockState::Air); - assert!(is_standable(&BlockPos::new(0, 1, 0), &dim)); - assert!(!is_standable(&BlockPos::new(0, 0, 0), &dim)); - assert!(!is_standable(&BlockPos::new(0, 2, 0), &dim)); + assert!(is_standable(&BlockPos::new(0, 1, 0), &world)); + assert!(!is_standable(&BlockPos::new(0, 0, 0), &world)); + assert!(!is_standable(&BlockPos::new(0, 2, 0), &world)); } } diff --git a/bot/src/main.rs b/bot/src/main.rs index ce627651..dd542a1c 100755 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -59,7 +59,7 @@ async fn handle(bot: Client, event: Event, _state: State) -> anyhow::Result<()> println!("{}", m.message().to_ansi(None)); if m.message().to_string() == " goto" { let target_pos_vec3 = *(bot - .dimension + .world .read() .entity_by_uuid(&uuid::uuid!("6536bfed869548fd83a1ecd24cf2a0fd")) .unwrap() From 00bfcde391c0f02e4eb9e7fb9f562ecebaeabb6d Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 17 Nov 2022 17:42:30 +0000 Subject: [PATCH 6/6] move some stuff to the azalea_client::chat mod --- azalea-client/src/chat.rs | 25 ++++++++++++++++++++++--- azalea-client/src/client.rs | 21 +-------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index 5eadc0c3..24ccbfd5 100755 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -1,13 +1,32 @@ -use std::time::{SystemTime, UNIX_EPOCH}; +//! Implementations of chat-related features. +use crate::Client; +use azalea_chat::Component; use azalea_crypto::MessageSignature; use azalea_protocol::packets::game::{ - clientbound_player_chat_packet::LastSeenMessagesUpdate, + clientbound_player_chat_packet::{ClientboundPlayerChatPacket, LastSeenMessagesUpdate}, + clientbound_system_chat_packet::ClientboundSystemChatPacket, serverbound_chat_command_packet::ServerboundChatCommandPacket, serverbound_chat_packet::ServerboundChatPacket, }; +use std::time::{SystemTime, UNIX_EPOCH}; -use crate::Client; +/// A chat packet, either a system message or a chat message. +#[derive(Debug, Clone)] +pub enum ChatPacket { + System(ClientboundSystemChatPacket), + Player(Box), +} + +impl ChatPacket { + /// Get the message shown in chat for this packet. + pub fn message(&self) -> Component { + match self { + ChatPacket::System(p) => p.content.clone(), + ChatPacket::Player(p) => p.message(false), + } + } +} impl Client { /// Sends chat message to the server. This only sends the chat packet and diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 85e5013e..326ba002 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -1,13 +1,11 @@ +pub use crate::chat::ChatPacket; use crate::{movement::WalkDirection, plugins::Plugins, Account, Player}; use azalea_auth::game_profile::GameProfile; -use azalea_chat::Component; use azalea_core::{ChunkPos, ResourceLocation, Vec3}; use azalea_protocol::{ connect::{Connection, ConnectionError, ReadConnection, WriteConnection}, packets::{ game::{ - clientbound_player_chat_packet::ClientboundPlayerChatPacket, - clientbound_system_chat_packet::ClientboundSystemChatPacket, serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, serverbound_client_information_packet::ServerboundClientInformationPacket, serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, @@ -63,23 +61,6 @@ pub enum Event { Packet(Box), } -/// A chat packet, either a system message or a chat message. -#[derive(Debug, Clone)] -pub enum ChatPacket { - System(ClientboundSystemChatPacket), - Player(Box), -} - -impl ChatPacket { - /// Get the message shown in chat for this packet. - pub fn message(&self) -> Component { - match self { - ChatPacket::System(p) => p.content.clone(), - ChatPacket::Player(p) => p.message(false), - } - } -} - /// A player that you control that is currently in a Minecraft server. #[derive(Clone)] pub struct Client {