aboutsummaryrefslogtreecommitdiff
path: root/azalea-client
diff options
context:
space:
mode:
Diffstat (limited to 'azalea-client')
-rw-r--r--azalea-client/src/client.rs2
-rw-r--r--azalea-client/src/interact.rs23
-rw-r--r--azalea-client/src/lib.rs1
-rw-r--r--azalea-client/src/local_player.rs7
-rw-r--r--azalea-client/src/packet_handling.rs25
-rw-r--r--azalea-client/src/respawn.rs38
6 files changed, 76 insertions, 20 deletions
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index 7a4285e6..f2e91dfa 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -11,6 +11,7 @@ use crate::{
movement::{LastSentLookDirection, PlayerMovePlugin},
packet_handling::{self, PacketHandlerPlugin, PacketReceiver},
player::retroactively_add_game_profile_component,
+ respawn::RespawnPlugin,
task_pool::TaskPoolPlugin,
Account, PlayerInfo,
};
@@ -717,6 +718,7 @@ impl PluginGroup for DefaultPlugins {
.add(DisconnectPlugin)
.add(PlayerMovePlugin)
.add(InteractPlugin)
+ .add(RespawnPlugin)
.add(TickBroadcastPlugin)
}
}
diff --git a/azalea-client/src/interact.rs b/azalea-client/src/interact.rs
index ec5ed87b..2da80760 100644
--- a/azalea-client/src/interact.rs
+++ b/azalea-client/src/interact.rs
@@ -6,7 +6,7 @@ use azalea_protocol::packets::game::{
};
use azalea_world::{
entity::{clamp_look_direction, view_vector, EyeHeight, LookDirection, Position, WorldName},
- InstanceContainer,
+ Instance, InstanceContainer,
};
use bevy_app::{App, Plugin};
use bevy_ecs::{
@@ -153,13 +153,13 @@ fn update_hit_result_component(
y: position.y + **eye_height as f64,
z: position.z,
};
- let hit_result = pick(
- look_direction,
- &eye_position,
- world_name,
- &instance_container,
- pick_range,
- );
+
+ let Some(instance_lock) = instance_container.get(world_name) else {
+ continue;
+ };
+ let instance = instance_lock.read();
+
+ let hit_result = pick(look_direction, &eye_position, &instance, pick_range);
if let Some(mut hit_result_ref) = hit_result_ref {
**hit_result_ref = hit_result;
} else {
@@ -178,16 +178,11 @@ fn update_hit_result_component(
pub fn pick(
look_direction: &LookDirection,
eye_position: &Vec3,
- world_name: &WorldName,
- instance_container: &InstanceContainer,
+ instance: &Instance,
pick_range: f64,
) -> BlockHitResult {
let view_vector = view_vector(look_direction);
let end_position = eye_position + &(view_vector * pick_range);
- let instance_lock = instance_container
- .get(world_name)
- .expect("entities must always be in a valid world");
- let instance = instance_lock.read();
azalea_physics::clip::clip(
&instance.chunks,
ClipContext {
diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs
index c198ced3..2c08033b 100644
--- a/azalea-client/src/lib.rs
+++ b/azalea-client/src/lib.rs
@@ -25,6 +25,7 @@ mod movement;
pub mod packet_handling;
pub mod ping;
mod player;
+pub mod respawn;
pub mod task_pool;
pub use account::{Account, AccountOpts};
diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs
index 423b4308..691f9ced 100644
--- a/azalea-client/src/local_player.rs
+++ b/azalea-client/src/local_player.rs
@@ -139,9 +139,10 @@ pub fn update_in_loaded_chunk(
) {
for (entity, local_player, position) in &query {
let player_chunk_pos = ChunkPos::from(position);
- let instance_lock = instance_container
- .get(local_player)
- .expect("local player should always be in an instance");
+ let Some(instance_lock) = instance_container.get(local_player) else {
+ continue;
+ };
+
let in_loaded_chunk = instance_lock.read().chunks.get(&player_chunk_pos).is_some();
if in_loaded_chunk {
commands.entity(entity).insert(LocalPlayerInLoadedChunk);
diff --git a/azalea-client/src/packet_handling.rs b/azalea-client/src/packet_handling.rs
index 8ffff870..50887096 100644
--- a/azalea-client/src/packet_handling.rs
+++ b/azalea-client/src/packet_handling.rs
@@ -9,7 +9,9 @@ use azalea_protocol::{
serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket,
- ClientboundGamePacket, ServerboundGamePacket,
+ serverbound_pong_packet::ServerboundPongPacket,
+ serverbound_resource_pack_packet::ServerboundResourcePackPacket, ClientboundGamePacket,
+ ServerboundGamePacket,
},
read::ReadPacketError,
};
@@ -995,7 +997,15 @@ fn process_packet_events(ecs: &mut World) {
})
}
ClientboundGamePacket::OpenSignEditor(_) => {}
- ClientboundGamePacket::Ping(_) => {}
+ ClientboundGamePacket::Ping(p) => {
+ debug!("Got ping packet {:?}", p);
+
+ let mut system_state: SystemState<Query<&mut LocalPlayer>> = SystemState::new(ecs);
+ let mut query = system_state.get_mut(ecs);
+
+ let local_player = query.get_mut(player_entity).unwrap();
+ local_player.write_packet(ServerboundPongPacket { id: p.id }.get());
+ }
ClientboundGamePacket::PlaceGhostRecipe(_) => {}
ClientboundGamePacket::PlayerCombatEnd(_) => {}
ClientboundGamePacket::PlayerCombatEnter(_) => {}
@@ -1023,7 +1033,16 @@ fn process_packet_events(ecs: &mut World) {
}
ClientboundGamePacket::PlayerLookAt(_) => {}
ClientboundGamePacket::RemoveMobEffect(_) => {}
- ClientboundGamePacket::ResourcePack(_) => {}
+ ClientboundGamePacket::ResourcePack(p) => {
+ debug!("Got resource pack packet {:?}", p);
+
+ let mut system_state: SystemState<Query<&mut LocalPlayer>> = SystemState::new(ecs);
+ let mut query = system_state.get_mut(ecs);
+
+ let local_player = query.get_mut(player_entity).unwrap();
+ // always accept resource pack
+ local_player.write_packet(ServerboundResourcePackPacket { action: azalea_protocol::packets::game::serverbound_resource_pack_packet::Action::Accepted }.get());
+ }
ClientboundGamePacket::Respawn(p) => {
debug!("Got respawn packet {:?}", p);
diff --git a/azalea-client/src/respawn.rs b/azalea-client/src/respawn.rs
new file mode 100644
index 00000000..4e42157c
--- /dev/null
+++ b/azalea-client/src/respawn.rs
@@ -0,0 +1,38 @@
+use azalea_protocol::packets::game::serverbound_client_command_packet::{
+ self, ServerboundClientCommandPacket,
+};
+use bevy_app::{App, Plugin};
+use bevy_ecs::prelude::*;
+
+use crate::LocalPlayer;
+
+/// Tell the server that we're respawning.
+#[derive(Debug, Clone)]
+pub struct PerformRespawnEvent {
+ pub entity: Entity,
+}
+
+/// A plugin that makes [`PerformRespawnEvent`] send the packet to respawn.
+pub struct RespawnPlugin;
+impl Plugin for RespawnPlugin {
+ fn build(&self, app: &mut App) {
+ app.add_event::<PerformRespawnEvent>()
+ .add_system(perform_respawn);
+ }
+}
+
+pub fn perform_respawn(
+ mut events: EventReader<PerformRespawnEvent>,
+ mut query: Query<&mut LocalPlayer>,
+) {
+ for event in events.iter() {
+ if let Ok(local_player) = query.get_mut(event.entity) {
+ local_player.write_packet(
+ ServerboundClientCommandPacket {
+ action: serverbound_client_command_packet::Action::PerformRespawn,
+ }
+ .get(),
+ );
+ }
+ }
+}