From 41f61bf9c11ab58af4c1bd97c2cb40110b272449 Mon Sep 17 00:00:00 2001 From: mat Date: Fri, 24 Jun 2022 23:54:31 -0500 Subject: [PATCH] i hate mutexes --- azalea-client/src/client.rs | 159 +++++++++--------- azalea-client/src/movement.rs | 5 + azalea-entity/src/lib.rs | 4 +- .../clientbound_player_position_packet.rs | 2 +- azalea-protocol/src/packets/game/mod.rs | 2 + ...serverbound_accept_teleportation_packet.rs | 8 + codegen/lib/code/packet.py | 2 +- 7 files changed, 96 insertions(+), 86 deletions(-) create mode 100644 azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 943e0f9f..364abef6 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -8,8 +8,10 @@ use azalea_protocol::{ game::{ clientbound_player_chat_packet::ClientboundPlayerChatPacket, clientbound_system_chat_packet::ClientboundSystemChatPacket, + serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, - serverbound_keep_alive_packet::ServerboundKeepAlivePacket, GamePacket, + serverbound_keep_alive_packet::ServerboundKeepAlivePacket, + serverbound_move_player_packet_pos_rot::ServerboundMovePlayerPacketPosRot, GamePacket, }, handshake::client_intention_packet::ClientIntentionPacket, login::{ @@ -166,6 +168,9 @@ impl Client { let game_loop_state = client.state.clone(); + // if you get an error right here that means you're doing something with locks wrong + // read the error to see where the issue is + // you might be able to just drop the lock or put it in its own scope to fix tokio::spawn(Self::protocol_loop( conn.clone(), tx.clone(), @@ -352,94 +357,84 @@ impl Client { // TODO: reply with teleport confirm println!("Got player position packet {:?}", p); - let mut state_lock = state.lock()?; - let player_entity_id = state_lock.player.entity_id; - let world = state_lock.world.as_mut().unwrap(); - let player_entity = world - .mut_entity_by_id(player_entity_id) - .expect("Player entity doesn't exist"); - let delta_movement = &player_entity.delta; + let (new_pos, y_rot, x_rot) = { + let mut state_lock = state.lock()?; + let player_entity_id = state_lock.player.entity_id; + let world = state_lock.world.as_mut().unwrap(); + let player_entity = world + .mut_entity_by_id(player_entity_id) + .expect("Player entity doesn't exist"); + let delta_movement = &player_entity.delta; - let is_x_relative = p.relative_arguments.x; - let is_y_relative = p.relative_arguments.y; - let is_z_relative = p.relative_arguments.z; + let is_x_relative = p.relative_arguments.x; + let is_y_relative = p.relative_arguments.y; + let is_z_relative = p.relative_arguments.z; - let (delta_x, new_pos_x) = if is_x_relative { - player_entity.old_pos.x += p.x; - (delta_movement.x(), player_entity.pos().x + p.x) - } else { - player_entity.old_pos.x = p.x; - (0.0, p.x) - }; - let (delta_y, new_pos_y) = if is_y_relative { - player_entity.old_pos.y += p.y; - (delta_movement.y(), player_entity.pos().y + p.y) - } else { - player_entity.old_pos.y = p.y; - (0.0, p.y) - }; - let (delta_z, new_pos_z) = if is_z_relative { - player_entity.old_pos.z += p.z; - (delta_movement.z(), player_entity.pos().z + p.z) - } else { - player_entity.old_pos.z = p.z; - (0.0, p.z) + let (delta_x, new_pos_x) = if is_x_relative { + player_entity.old_pos.x += p.x; + (delta_movement.x(), player_entity.pos().x + p.x) + } else { + player_entity.old_pos.x = p.x; + (0.0, p.x) + }; + let (delta_y, new_pos_y) = if is_y_relative { + player_entity.old_pos.y += p.y; + (delta_movement.y(), player_entity.pos().y + p.y) + } else { + player_entity.old_pos.y = p.y; + (0.0, p.y) + }; + let (delta_z, new_pos_z) = if is_z_relative { + player_entity.old_pos.z += p.z; + (delta_movement.z(), player_entity.pos().z + p.z) + } else { + player_entity.old_pos.z = p.z; + (0.0, p.z) + }; + + let mut y_rot = p.y_rot; + let mut x_rot = p.x_rot; + if p.relative_arguments.x_rot { + y_rot += player_entity.x_rot; + } + if p.relative_arguments.y_rot { + x_rot += player_entity.y_rot; + } + + player_entity.delta = PositionDelta { + xa: delta_x, + ya: delta_y, + za: delta_z, + }; + player_entity.set_rotation(y_rot, x_rot); + // TODO: minecraft sets "xo", "yo", and "zo" here but idk what that means + // so investigate that ig + let new_pos = EntityPos { + x: new_pos_x, + y: new_pos_y, + z: new_pos_z, + }; + world + .move_entity(player_entity_id, new_pos) + .expect("The player entity should always exist"); + + (new_pos, y_rot, x_rot) }; - let mut y_rot = p.y_rot; - let mut x_rot = p.x_rot; - if p.relative_arguments.x_rot { - y_rot += player_entity.x_rot; - } - if p.relative_arguments.y_rot { - x_rot += player_entity.y_rot; - } - - player_entity.delta = PositionDelta { - xa: delta_x, - ya: delta_y, - za: delta_z, - }; - player_entity.set_rotation(x_rot, y_rot); - // TODO: minecraft sets "xo", "yo", and "zo" here but idk what that means - // so investigate that ig - world - .move_entity( - player_entity_id, - EntityPos { - x: new_pos_x, - y: new_pos_y, - z: new_pos_z, - }, - ) - .expect("The player entity should always exist"); - - let mut state_lock = state.lock()?; - - let player = &state_lock.player; - let player_entity_id = player.entity_id; - - let world = state_lock.world.as_mut().unwrap(); - world.move_entity( - player_entity_id, - EntityPos { - x: p.x, - y: p.y, - z: p.z, - }, - )?; - - conn.lock() - .await - .write(ServerboundAcceptTeleportationPacket {}.get()) + let mut conn_lock = conn.lock().await; + conn_lock + .write(ServerboundAcceptTeleportationPacket { id: p.id }.get()) .await; - conn.lock() - .await + conn_lock .write( ServerboundMovePlayerPacketPosRot { - identifier: ResourceLocation::new("brand").unwrap(), - // they don't have to know :) - data: "vanilla".into(), + x: new_pos.x, + y: new_pos.y, + z: new_pos.z, + y_rot, + x_rot, + // this is always false + on_ground: false, } .get(), ) diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs index 0402b15b..f74d48df 100644 --- a/azalea-client/src/movement.rs +++ b/azalea-client/src/movement.rs @@ -5,7 +5,9 @@ use azalea_protocol::packets::game::serverbound_move_player_packet_pos_rot::Serv impl Client { /// Set the client's position to the given coordinates. pub async fn move_to(&mut self, new_pos: EntityPos) -> Result<(), String> { + println!("obtaining lock on state"); let mut state_lock = self.state.lock().unwrap(); + println!("obtained lock on state"); let world = state_lock.world.as_ref().unwrap(); @@ -18,7 +20,9 @@ impl Client { let world = state_lock.world.as_mut().unwrap(); world.move_entity(player_id, new_pos)?; + drop(state_lock); + println!("obtaining lock on conn"); self.conn .lock() .await @@ -34,6 +38,7 @@ impl Client { .get(), ) .await; + println!("obtained lock on conn"); Ok(()) } diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs index 63c717d3..9436d753 100644 --- a/azalea-entity/src/lib.rs +++ b/azalea-entity/src/lib.rs @@ -42,9 +42,9 @@ impl Entity { self.pos = new_pos; } - pub fn set_rotation(&mut self, x_rot: f32, y_rot: f32) { - self.x_rot = x_rot % 360.0; + pub fn set_rotation(&mut self, y_rot: f32, x_rot: f32) { self.y_rot = y_rot.clamp(-90.0, 90.0) % 360.0; + self.x_rot = x_rot % 360.0; // TODO: minecraft also sets yRotO and xRotO to xRot and yRot ... but idk what they're used for so } } diff --git a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs index 2c5504fa..29f7c1a3 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_position_packet.rs @@ -14,7 +14,7 @@ pub struct ClientboundPlayerPositionPacket { /// Client should confirm this packet with Teleport Confirm containing the /// same Teleport ID. #[var] - pub id: i32, + pub id: u32, pub dismount_vehicle: bool, } diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index d3d6650c..3e492dec 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -49,6 +49,7 @@ pub mod clientbound_update_attributes_packet; pub mod clientbound_update_recipes_packet; pub mod clientbound_update_tags_packet; pub mod clientbound_update_view_distance_packet; +pub mod serverbound_accept_teleportation_packet; pub mod serverbound_chat_command_packet; pub mod serverbound_chat_preview_packet; pub mod serverbound_custom_payload_packet; @@ -63,6 +64,7 @@ use packet_macros::declare_state_packets; declare_state_packets!( GamePacket, Serverbound => { + 0x00: serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, 0x03: serverbound_chat_command_packet::ServerboundChatCommandPacket, 0x05: serverbound_chat_preview_packet::ServerboundChatPreviewPacket, 0x0c: serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, diff --git a/azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs b/azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs new file mode 100644 index 00000000..98a9f728 --- /dev/null +++ b/azalea-protocol/src/packets/game/serverbound_accept_teleportation_packet.rs @@ -0,0 +1,8 @@ +use azalea_buf::McBuf; +use packet_macros::GamePacket; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ServerboundAcceptTeleportationPacket { + #[var] + pub id: u32, +} diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py index b4ca8be7..de8254e7 100644 --- a/codegen/lib/code/packet.py +++ b/codegen/lib/code/packet.py @@ -30,7 +30,7 @@ def generate_packet(burger_packets, mappings: Mappings, target_packet_id, target generated_packet_code.append( f'#[derive(Clone, Debug, McBuf, {to_camel_case(state)}Packet)]') uses.add(f'packet_macros::{to_camel_case(state)}Packet') - uses.add(f'packet_buf::McBuf') + uses.add(f'azalea_buf::McBuf') obfuscated_class_name = packet['class'].split('.')[0] class_name = mappings.get_class(