1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00
This commit is contained in:
mat 2022-09-05 01:04:16 -05:00
parent 4f00ddace0
commit 9ca9519469
9 changed files with 164 additions and 20 deletions

1
Cargo.lock generated
View file

@ -156,6 +156,7 @@ dependencies = [
"anyhow",
"azalea-auth",
"azalea-block",
"azalea-chat",
"azalea-core",
"azalea-crypto",
"azalea-physics",

View file

@ -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(())
}
}

View file

@ -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"}

View file

@ -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);

View file

@ -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)]

View file

@ -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,
}

View file

@ -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;

View file

@ -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,

View file

@ -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();