1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

everything compiles

This commit is contained in:
Ubuntu 2023-01-20 19:01:52 +00:00
parent 8921ae4887
commit 8ea3d728c1
8 changed files with 76 additions and 35 deletions

View file

@ -4,7 +4,9 @@ use uuid::Uuid;
#[derive(McBuf, Debug, Clone, Default)]
pub struct GameProfile {
/// The UUID of the player.
pub uuid: Uuid,
/// The username of the player.
pub name: String,
pub properties: HashMap<String, ProfilePropertyValue>,
}

View file

@ -153,7 +153,7 @@ impl Client {
/// # Ok(())
/// # }
/// ```
pub async fn chat(&self, message: &str) {
pub fn chat(&self, message: &str) {
if let Some(command) = message.strip_prefix('/') {
self.send_command_packet(command);
} else {

View file

@ -1,7 +1,7 @@
pub use crate::chat::ChatPacket;
use crate::{
local_player::{
death_event, send_tick_event, update_in_loaded_chunk, LocalPlayer, PhysicsState,
death_event, send_tick_event, update_in_loaded_chunk, LocalPlayer, PhysicsState, GameProfileComponent,
},
movement::{local_player_ai_step, send_position, sprint_listener, walk_listener},
packet_handling::{self, PacketHandlerPlugin},
@ -232,7 +232,6 @@ impl Client {
let mut local_player = crate::local_player::LocalPlayer::new(
entity,
game_profile,
packet_writer_sender,
// default to an empty world, it'll be set correctly later when we
// get the login packet
@ -258,6 +257,7 @@ impl Client {
ecs.entity_mut(entity).insert((
local_player,
packet_receiver,
GameProfileComponent(game_profile),
PhysicsState::default(),
Local,
));

View file

@ -25,12 +25,34 @@ impl Client {
///
/// You can then use [`Self::map_entity`] to get components from this
/// entity.
///
/// # Example
/// Note that this will very likely change in the future.
/// ```
/// let entity = bot.entity_by::<With<Player>, (&GameProfileComponent,)>(
/// |profile: &&GameProfileComponent| profile.name == sender,
/// );
/// if let Some(entity) = entity {
/// let position = bot.entity_components::<Position>(entity);
/// }
/// ```
pub fn entity_by<F: ReadOnlyWorldQuery, Q: ReadOnlyWorldQuery>(
&mut self,
predicate: impl EntityPredicate<Q, F>,
) -> Option<Entity> {
predicate.find(self.ecs.clone())
}
/// Get a component from an entity. Note that this will return an owned type
/// (i.e. not a reference) so it may be expensive for larger types.
pub fn entity_components<Q: Component + Clone>(&mut self, entity: Entity) -> Q {
let mut ecs = self.ecs.lock();
let mut q = ecs.query::<&Q>();
let components = q
.get(&ecs, entity)
.expect("Entity components must be present in Client::entity)components.");
components.clone()
}
}
pub trait EntityPredicate<Q: ReadOnlyWorldQuery, Filter: ReadOnlyWorldQuery> {

View file

@ -26,7 +26,7 @@ mod plugins;
pub use account::Account;
pub use bevy_ecs as ecs;
pub use client::{start_ecs, ChatPacket, Client, ClientInformation, Event, JoinError};
pub use local_player::LocalPlayer;
pub use local_player::{GameProfileComponent, LocalPlayer};
pub use movement::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
pub use player::PlayerInfo;
pub use plugins::{Plugin, PluginState, PluginStates, Plugins};

View file

@ -8,6 +8,7 @@ use azalea_world::{
EntityInfos, PartialWorld, World,
};
use bevy_ecs::{component::Component, query::Added, system::Query};
use derive_more::{Deref, DerefMut};
use log::warn;
use parking_lot::RwLock;
use thiserror::Error;
@ -19,8 +20,6 @@ use crate::{ClientInformation, Event, PlayerInfo, WalkDirection};
/// A player that you control that is currently in a Minecraft server.
#[derive(Component)]
pub struct LocalPlayer {
pub profile: GameProfile,
pub packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
pub client_information: ClientInformation,
@ -59,6 +58,14 @@ pub struct PhysicsState {
pub left_impulse: f32,
}
/// A component only present in players that contains the [`GameProfile`] (which
/// you can use to get a player's name).
///
/// Note that it's possible for this to be missing in a player if the server
/// never sent the player info for them (though this is uncommon).
#[derive(Component, Clone, Debug, Deref, DerefMut)]
pub struct GameProfileComponent(pub GameProfile);
/// Marks a [`LocalPlayer`] that's in a loaded chunk. This is updated at the
/// beginning of every tick.
#[derive(Component)]
@ -71,7 +78,6 @@ impl LocalPlayer {
/// defaults, otherwise use [`Client::join`].
pub fn new(
entity: Entity,
profile: GameProfile,
packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
world: Arc<RwLock<World>>,
tx: mpsc::UnboundedSender<Event>,
@ -79,8 +85,6 @@ impl LocalPlayer {
let client_information = ClientInformation::default();
LocalPlayer {
profile,
packet_writer,
client_information: ClientInformation::default(),

View file

@ -31,7 +31,10 @@ use log::{debug, error, trace, warn};
use parking_lot::Mutex;
use tokio::sync::mpsc;
use crate::{local_player::LocalPlayer, ChatPacket, ClientInformation, Event, PlayerInfo};
use crate::{
local_player::{GameProfileComponent, LocalPlayer},
ChatPacket, ClientInformation, Event, PlayerInfo,
};
pub struct PacketHandlerPlugin;
@ -89,13 +92,13 @@ fn handle_packets(ecs: &mut bevy_ecs::world::World) {
let mut system_state: SystemState<(
Commands,
Query<&mut LocalPlayer>,
Query<(&mut LocalPlayer, &GameProfileComponent)>,
ResMut<WorldContainer>,
ResMut<EntityInfos>,
)> = SystemState::new(ecs);
let (mut commands, mut query, mut world_container, mut entity_infos) =
system_state.get_mut(ecs);
let mut local_player = query.get_mut(player_entity).unwrap();
let (mut local_player, game_profile) = query.get_mut(player_entity).unwrap();
{
// TODO: have registry_holder be a struct because this sucks rn
@ -172,7 +175,7 @@ fn handle_packets(ecs: &mut bevy_ecs::world::World) {
let player_bundle = PlayerBundle {
entity: EntityBundle::new(
local_player.profile.uuid,
game_profile.uuid,
Vec3::default(),
azalea_registry::EntityKind::Player,
world_name,
@ -527,6 +530,7 @@ fn handle_packets(ecs: &mut bevy_ecs::world::World) {
LoadedBy(HashSet::from([player_entity])),
bundle,
));
println!("spawned player entity: {:?}", spawned.id());
} else {
warn!("got add player packet but we haven't gotten a login packet yet");

View file

@ -5,7 +5,7 @@ use azalea::entity::metadata::Player;
use azalea::entity::Position;
use azalea::pathfinder::BlockPosGoal;
// use azalea::ClientInformation;
use azalea::{prelude::*, BlockPos, Swarm, SwarmEvent, WalkDirection};
use azalea::{prelude::*, BlockPos, GameProfileComponent, Swarm, SwarmEvent, WalkDirection};
use azalea::{Account, Client, Event};
use azalea_protocol::packets::game::serverbound_client_command_packet::ServerboundClientCommandPacket;
use std::time::Duration;
@ -103,28 +103,37 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
// .iter(&mut ecs)
// .find(|e| e.name() == Some(sender));
// let entity = bot.entity_by::<With<Player>>(|name: &Name| name == sender);
// let entity = bot.entity_by(|name: &Name| name == sender);
let entity = bot.entity_by::<With<Player>, (&Position,)>(|pos: &&Position| true);
let entity = bot.entity_by::<With<Player>, (&GameProfileComponent,)>(
|profile: &&GameProfileComponent| profile.name == sender,
);
if let Some(entity) = entity {
// if m.content() == "goto" {
// let target_pos_vec3 = entity.pos();
// let target_pos: BlockPos = target_pos_vec3.into();
// bot.goto(BlockPosGoal::from(target_pos));
// } else if m.content() == "look" {
// let target_pos_vec3 = entity.pos();
// let target_pos: BlockPos = target_pos_vec3.into();
// println!("target_pos: {:?}", target_pos);
// bot.look_at(target_pos.center());
// } else if m.content() == "jump" {
// bot.set_jumping(true);
// } else if m.content() == "walk" {
// bot.walk(WalkDirection::Forward);
// } else if m.content() == "stop" {
// bot.set_jumping(false);
// bot.walk(WalkDirection::None);
// } else if m.content() == "lag" {
// std::thread::sleep(Duration::from_millis(1000));
// }
match m.content().as_str() {
"goto" => {
let entity_pos = bot.entity_components::<Position>(entity);
let target_pos: BlockPos = entity_pos.into();
bot.goto(BlockPosGoal::from(target_pos));
}
"look" => {
let entity_pos = bot.entity_components::<Position>(entity);
let target_pos: BlockPos = entity_pos.into();
println!("target_pos: {:?}", target_pos);
bot.look_at(target_pos.center());
}
"jump" => {
bot.set_jumping(true);
}
"walk" => {
bot.walk(WalkDirection::Forward);
}
"stop" => {
bot.set_jumping(false);
bot.walk(WalkDirection::None);
}
"lag" => {
std::thread::sleep(Duration::from_millis(1000));
}
_ => {}
}
}
}
Event::Death(_) => {