mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
.walk :)
This commit is contained in:
parent
4f00ddace0
commit
9ca9519469
9 changed files with 164 additions and 20 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -156,6 +156,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"azalea-auth",
|
||||
"azalea-block",
|
||||
"azalea-chat",
|
||||
"azalea-core",
|
||||
"azalea-crypto",
|
||||
"azalea-physics",
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use std::io::{Read, Write};
|
||||
use std::{
|
||||
fmt::Display,
|
||||
io::{Read, Write},
|
||||
};
|
||||
|
||||
use azalea_buf::{BufReadError, McBufReadable, McBufWritable};
|
||||
use serde::{de, Deserialize, Deserializer};
|
||||
|
@ -293,3 +296,28 @@ impl McBufWritable for Component {
|
|||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Component {
|
||||
fn from(s: String) -> Self {
|
||||
Component::Text(TextComponent {
|
||||
text: s,
|
||||
base: BaseComponent::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Component {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// this contains the final string will all the ansi escape codes
|
||||
for component in self.clone().into_iter() {
|
||||
let component_text = match &component {
|
||||
Self::Text(c) => c.text.to_string(),
|
||||
Self::Translatable(c) => c.to_string(),
|
||||
};
|
||||
|
||||
f.write_str(&component_text)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ version = "0.1.0"
|
|||
anyhow = "1.0.59"
|
||||
azalea-auth = {path = "../azalea-auth"}
|
||||
azalea-block = {path = "../azalea-block"}
|
||||
azalea-chat = {path = "../azalea-chat"}
|
||||
azalea-core = {path = "../azalea-core"}
|
||||
azalea-crypto = {path = "../azalea-crypto"}
|
||||
azalea-physics = {path = "../azalea-physics"}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{Account, Player};
|
||||
use crate::{movement::MoveDirection, Account, Player};
|
||||
use azalea_auth::game_profile::GameProfile;
|
||||
use azalea_block::BlockState;
|
||||
use azalea_chat::component::Component;
|
||||
use azalea_core::{ChunkPos, ResourceLocation, Vec3};
|
||||
use azalea_protocol::{
|
||||
connect::{Connection, ConnectionError},
|
||||
|
@ -52,14 +53,14 @@ pub enum ChatPacket {
|
|||
Player(Box<ClientboundPlayerChatPacket>),
|
||||
}
|
||||
|
||||
// impl ChatPacket {
|
||||
// pub fn message(&self) -> &str {
|
||||
// match self {
|
||||
// ChatPacket::System(p) => &p.content,
|
||||
// ChatPacket::Player(p) => &p.message,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
impl ChatPacket {
|
||||
pub fn message(&self) -> Component {
|
||||
match self {
|
||||
ChatPacket::System(p) => p.content.clone(),
|
||||
ChatPacket::Player(p) => p.message.message(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A player that you can control that is currently in a Minecraft server.
|
||||
#[derive(Clone)]
|
||||
|
@ -68,9 +69,17 @@ pub struct Client {
|
|||
pub conn: Arc<tokio::sync::Mutex<Connection<ClientboundGamePacket, ServerboundGamePacket>>>,
|
||||
pub player: Arc<Mutex<Player>>,
|
||||
pub dimension: Arc<Mutex<Dimension>>,
|
||||
pub physics_state: Arc<Mutex<PhysicsState>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PhysicsState {
|
||||
/// Minecraft only sends a movement packet either after 20 ticks or if the player moved enough. This is that tick counter.
|
||||
pub position_remainder: u32,
|
||||
|
||||
pub move_direction: MoveDirection,
|
||||
pub forward_impulse: f32,
|
||||
pub left_impulse: f32,
|
||||
}
|
||||
|
||||
/// Whether we should ignore errors when decoding packets.
|
||||
|
@ -185,8 +194,7 @@ impl Client {
|
|||
conn,
|
||||
player: Arc::new(Mutex::new(Player::default())),
|
||||
dimension: Arc::new(Mutex::new(Dimension::default())),
|
||||
|
||||
position_remainder: 0,
|
||||
physics_state: Arc::new(Mutex::new(PhysicsState::default())),
|
||||
};
|
||||
|
||||
// just start up the game loop and we're ready!
|
||||
|
@ -552,8 +560,8 @@ impl Client {
|
|||
.move_entity_with_delta(p.entity_id, &p.delta)
|
||||
.map_err(|e| HandleError::Other(e.into()))?;
|
||||
}
|
||||
ClientboundGamePacket::ClientboundMoveEntityRotPacket(p) => {
|
||||
println!("Got move entity rot packet {:?}", p);
|
||||
ClientboundGamePacket::ClientboundMoveEntityRotPacket(_p) => {
|
||||
// println!("Got move entity rot packet {:?}", p);
|
||||
}
|
||||
ClientboundGamePacket::ClientboundKeepAlivePacket(p) => {
|
||||
println!("Got keep alive packet {:?}", p);
|
||||
|
|
|
@ -8,6 +8,7 @@ mod player;
|
|||
|
||||
pub use account::Account;
|
||||
pub use client::{Client, Event};
|
||||
pub use movement::MoveDirection;
|
||||
pub use player::Player;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -32,7 +32,7 @@ impl Client {
|
|||
pub async fn send_position(&mut self) -> Result<(), MovePlayerError> {
|
||||
let packet = {
|
||||
let player_lock = self.player.lock().unwrap();
|
||||
|
||||
let mut physics_state = self.physics_state.lock().unwrap();
|
||||
let mut dimension_lock = self.dimension.lock().unwrap();
|
||||
|
||||
let mut player_entity = player_lock
|
||||
|
@ -52,12 +52,12 @@ impl Client {
|
|||
let y_rot_delta = (player_entity.y_rot - player_entity.y_rot_last) as f64;
|
||||
let x_rot_delta = (player_entity.x_rot - player_entity.x_rot_last) as f64;
|
||||
|
||||
self.position_remainder += 1;
|
||||
physics_state.position_remainder += 1;
|
||||
|
||||
// boolean sendingPosition = Mth.lengthSquared(xDelta, yDelta, zDelta) > Mth.square(2.0E-4D) || this.positionReminder >= 20;
|
||||
let sending_position = ((x_delta.powi(2) + y_delta.powi(2) + z_delta.powi(2))
|
||||
> 2.0e-4f64.powi(2))
|
||||
|| self.position_remainder >= 20;
|
||||
|| physics_state.position_remainder >= 20;
|
||||
let sending_rotation = y_rot_delta != 0.0 || x_rot_delta != 0.0;
|
||||
|
||||
// if self.is_passenger() {
|
||||
|
@ -107,7 +107,7 @@ impl Client {
|
|||
|
||||
if sending_position {
|
||||
player_entity.last_pos = *player_entity.pos();
|
||||
self.position_remainder = 0;
|
||||
physics_state.position_remainder = 0;
|
||||
}
|
||||
if sending_rotation {
|
||||
player_entity.y_rot_last = player_entity.y_rot;
|
||||
|
@ -155,6 +155,8 @@ impl Client {
|
|||
}
|
||||
|
||||
pub fn ai_step(&mut self) {
|
||||
self.tick_controls(None);
|
||||
|
||||
let player_lock = self.player.lock().unwrap();
|
||||
let mut dimension_lock = self.dimension.lock().unwrap();
|
||||
|
||||
|
@ -162,6 +164,67 @@ impl Client {
|
|||
.entity_mut(&mut dimension_lock)
|
||||
.expect("Player must exist");
|
||||
|
||||
// server ai step
|
||||
{
|
||||
let physics_state = self.physics_state.lock().unwrap();
|
||||
player_entity.xxa = physics_state.left_impulse;
|
||||
player_entity.zza = physics_state.forward_impulse;
|
||||
}
|
||||
|
||||
player_entity.ai_step();
|
||||
}
|
||||
|
||||
/// Update the impulse from self.move_direction. The multipler is used for sneaking.
|
||||
pub(crate) fn tick_controls(&mut self, multiplier: Option<f32>) {
|
||||
let mut physics_state = self.physics_state.lock().unwrap();
|
||||
|
||||
let mut forward_impulse: f32 = 0.;
|
||||
let mut left_impulse: f32 = 0.;
|
||||
match physics_state.move_direction {
|
||||
MoveDirection::Forward | MoveDirection::ForwardRight | MoveDirection::ForwardLeft => {
|
||||
forward_impulse += 1.;
|
||||
}
|
||||
MoveDirection::Backward
|
||||
| MoveDirection::BackwardRight
|
||||
| MoveDirection::BackwardLeft => {
|
||||
forward_impulse -= 1.;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
match physics_state.move_direction {
|
||||
MoveDirection::Right | MoveDirection::ForwardRight | MoveDirection::BackwardRight => {
|
||||
left_impulse += 1.;
|
||||
}
|
||||
MoveDirection::Left | MoveDirection::ForwardLeft | MoveDirection::BackwardLeft => {
|
||||
left_impulse -= 1.;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
physics_state.forward_impulse = forward_impulse;
|
||||
physics_state.left_impulse = left_impulse;
|
||||
|
||||
if let Some(multiplier) = multiplier {
|
||||
physics_state.forward_impulse *= multiplier;
|
||||
physics_state.left_impulse *= multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk(&mut self, direction: MoveDirection) {
|
||||
let mut physics_state = self.physics_state.lock().unwrap();
|
||||
physics_state.move_direction = direction;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub enum MoveDirection {
|
||||
#[default]
|
||||
None,
|
||||
Forward,
|
||||
Backward,
|
||||
Left,
|
||||
Right,
|
||||
ForwardRight,
|
||||
ForwardLeft,
|
||||
BackwardRight,
|
||||
BackwardLeft,
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ impl HasPhysics for EntityMut<'_> {
|
|||
if self.delta.z.abs() < 0.003 {
|
||||
self.delta.z = 0.;
|
||||
}
|
||||
|
||||
self.xxa *= 0.98;
|
||||
self.zza *= 0.98;
|
||||
|
||||
|
|
|
@ -49,6 +49,20 @@ pub struct SignedMessageBody {
|
|||
pub last_seen: Vec<LastSeenMessagesEntry>,
|
||||
}
|
||||
|
||||
impl PlayerChatMessage {
|
||||
pub fn message(&self, only_secure_chat: bool) -> Component {
|
||||
if only_secure_chat {
|
||||
return self
|
||||
.signed_body
|
||||
.content
|
||||
.decorated
|
||||
.clone()
|
||||
.unwrap_or(Component::from(self.signed_body.content.plain.clone()));
|
||||
}
|
||||
self.unsigned_content.clone().unwrap_or(self.message(true))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, McBuf)]
|
||||
pub struct LastSeenMessagesEntry {
|
||||
pub profile_id: Uuid,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#![allow(unused_variables, unused_imports)]
|
||||
use azalea_client::{Account, Event};
|
||||
use azalea_client::{Account, Event, MoveDirection};
|
||||
use azalea_core::{PositionXYZ, Vec3};
|
||||
use azalea_physics::collision::{HasCollision, MoverType};
|
||||
|
||||
|
@ -15,7 +15,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
// println!("{}", response.description.to_ansi(None));
|
||||
let account = Account::offline("bot");
|
||||
let (client, mut rx) = account.join(&address.try_into().unwrap()).await.unwrap();
|
||||
let (mut client, mut rx) = account.join(&address.try_into().unwrap()).await.unwrap();
|
||||
println!("connected");
|
||||
|
||||
while let Some(e) = &rx.recv().await {
|
||||
|
@ -41,6 +41,33 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
// // }
|
||||
// }
|
||||
Event::Chat(m) => {
|
||||
let message = m.message().to_string();
|
||||
println!("{}", message);
|
||||
|
||||
match &message[..] {
|
||||
"stop" => {
|
||||
println!("stopping");
|
||||
client.walk(MoveDirection::None);
|
||||
}
|
||||
"forward" => {
|
||||
println!("moving forward");
|
||||
client.walk(MoveDirection::Forward);
|
||||
}
|
||||
"backward" => {
|
||||
println!("moving backward");
|
||||
client.walk(MoveDirection::Backward);
|
||||
}
|
||||
"left" => {
|
||||
println!("moving left");
|
||||
client.walk(MoveDirection::Left);
|
||||
}
|
||||
"right" => {
|
||||
println!("moving right");
|
||||
client.walk(MoveDirection::Right);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// let new_pos = {
|
||||
// let dimension_lock = client.dimension.lock().unwrap();
|
||||
// let player = client.player.lock().unwrap();
|
||||
|
|
Loading…
Add table
Reference in a new issue