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:
parent
8921ae4887
commit
8ea3d728c1
8 changed files with 76 additions and 35 deletions
|
@ -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>,
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
));
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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(_) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue