From 7d901e39bc10a855b545d7b6c167f45148a1fb0a Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Wed, 7 Dec 2022 21:09:58 -0600 Subject: 1.19.3 (#34) * start updating to 22w42a * work a bit more on 22w42a * player chat packet * serverbound hello packet * Update mod.rs * add more stuff to clientbound player chat packet * ClientboundPlayerInfoUpdatePacket * features enabled and container closed * serverbound chat packets * make it compile * 22w43a * ServerboundChatSessionUpdatePacket * profile_public_key isn't Option anymore * Update bitset.rs * joining a server works * fix entitydatavalue * backtraces + fix clientbound chat message * fix some warnings and add more ecomments * 22w44a * generate en_us.json * add updating guide to codegen/readme * fix some markdown * update list of generated things * metadata stuff * Replace PJS generator mod with PixLyzer (#38) * pixlizer extractor * start working on shape extraction * fix generating language * fix pixlyzer shape generation * use empty_shape * generate blocks and shapes * update pixlyzer dir * Revert "update pixlyzer dir" This reverts commit ee9a0e7a49936dd8569c610ba9b6455895eeff71. * fix * fix * Revert "fix" This reverts commit ad12ddcb009ccc4eeb13ddef0871db1d9322ab7d. * fix * detect pixlyzer fail * fix pixlyzer * 22w45a * gen entities * add async-trait dep * update codegen/readme.md * explain when rust_log should be used * remove some unused code * start fixing pixlyzer issues * fix a thing in codegen * almost fixed * more progress towards 1.19.3 * 1.19.3-pre2 * fixes * revert some hardcoded property names * Delete clientbound_player_info_packet.rs * handle 1.19.3 player info packets * handle playerinforemove * start updating to 1.19.3-rc1 * optional registries work * fix some issues with 1.19.3 chat doesn't work yet * aaaaaaaaaaaaaaaaa * oh * ignore unused shapes * uncomment generate_blocks * fix migrate * 1.19.3-rc2 * fix clippy warnings * 1.19.3-rc3 * split the azalea-buf macro into separate modules * improve Recipe in protocol * 1.19.3 --- azalea-client/src/chat.rs | 25 ++---- azalea-client/src/client.rs | 213 +++++++++++++++++--------------------------- azalea-client/src/lib.rs | 6 +- azalea-client/src/ping.rs | 2 +- 4 files changed, 93 insertions(+), 153 deletions(-) (limited to 'azalea-client/src') diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index 26f37d58..510bf043 100755 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -2,12 +2,11 @@ use crate::Client; use azalea_chat::Component; -use azalea_crypto::MessageSignature; use azalea_protocol::packets::game::{ - clientbound_player_chat_packet::{ClientboundPlayerChatPacket, LastSeenMessagesUpdate}, + clientbound_player_chat_packet::ClientboundPlayerChatPacket, clientbound_system_chat_packet::ClientboundSystemChatPacket, serverbound_chat_command_packet::ServerboundChatCommandPacket, - serverbound_chat_packet::ServerboundChatPacket, + serverbound_chat_packet::{LastSeenMessagesUpdate, ServerboundChatPacket}, }; use std::{ sync::Arc, @@ -33,7 +32,7 @@ impl ChatPacket { pub fn message(&self) -> Component { match self { ChatPacket::System(p) => p.content.clone(), - ChatPacket::Player(p) => p.message(false), + ChatPacket::Player(p) => p.message(), } } @@ -47,7 +46,7 @@ impl ChatPacket { // If it's a player chat packet, then the sender and content // are already split for us. Some(p.chat_type.name.to_string()), - p.message.content(false).to_string(), + p.body.content.clone(), ), ChatPacket::System(p) => { let message = p.content.to_string(); @@ -88,7 +87,7 @@ impl Client { /// so you should use that instead. pub async fn send_chat_packet(&self, message: &str) -> Result<(), std::io::Error> { // TODO: chat signing - let signature = sign_message(); + // let signature = sign_message(); let packet = ServerboundChatPacket { message: message.to_string(), timestamp: SystemTime::now() @@ -98,8 +97,7 @@ impl Client { .try_into() .expect("Instant should fit into a u64"), salt: azalea_crypto::make_salt(), - signature, - signed_preview: false, + signature: None, last_seen_messages: LastSeenMessagesUpdate::default(), } .get(); @@ -120,7 +118,6 @@ impl Client { .expect("Instant should fit into a u64"), salt: azalea_crypto::make_salt(), argument_signatures: vec![], - signed_preview: false, last_seen_messages: LastSeenMessagesUpdate::default(), } .get(); @@ -143,14 +140,10 @@ impl Client { self.send_chat_packet(message).await } } - - // will be used for when the server tells the client about a chat preview - // with custom formatting - // pub fn acknowledge_preview(&self, message: &str) {} } // TODO // MessageSigner, ChatMessageContent, LastSeenMessages -fn sign_message() -> MessageSignature { - MessageSignature::default() -} +// fn sign_message() -> MessageSignature { +// MessageSignature::default() +// } diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 1cd26aa8..17fb4840 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -1,8 +1,7 @@ pub use crate::chat::ChatPacket; use crate::{movement::WalkDirection, plugins::PluginStates, Account, PlayerInfo}; use azalea_auth::game_profile::GameProfile; -use azalea_chat::Component; -use azalea_core::{ChunkPos, GameType, ResourceLocation, Vec3}; +use azalea_core::{ChunkPos, ResourceLocation, Vec3}; use azalea_protocol::{ connect::{Connection, ConnectionError, ReadConnection, WriteConnection}, packets::{ @@ -22,8 +21,7 @@ use azalea_protocol::{ login::{ serverbound_custom_query_packet::ServerboundCustomQueryPacket, serverbound_hello_packet::ServerboundHelloPacket, - serverbound_key_packet::{NonceOrSaltSignature, ServerboundKeyPacket}, - ClientboundLoginPacket, + serverbound_key_packet::ServerboundKeyPacket, ClientboundLoginPacket, }, ConnectionProtocol, PROTOCOL_VERSION, }, @@ -37,6 +35,8 @@ use azalea_world::{ use log::{debug, error, info, trace, warn}; use parking_lot::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::{ + any, + backtrace::Backtrace, collections::HashMap, fmt::Debug, io::{self, Cursor}, @@ -52,8 +52,11 @@ use uuid::Uuid; pub type ClientInformation = ServerboundClientInformationPacket; -/// Events are sent before they're processed, so for example game ticks happen -/// at the beginning of a tick before anything has happened. +/// Something that happened in-game, such as a tick passing or chat message +/// being sent. +/// +/// Note: Events are sent before they're processed, so for example game ticks +/// happen at the beginning of a tick before anything has happened. #[derive(Debug, Clone)] pub enum Event { /// Happens right after the bot switches into the Game state, but before @@ -61,43 +64,26 @@ pub enum Event { /// information with `Client::set_client_information`, so the packet /// doesn't have to be sent twice. Init, + /// The client is now in the world. Fired when we receive a login packet. Login, + /// A chat message was sent in the game chat. Chat(ChatPacket), /// Happens 20 times per second, but only when the world is loaded. Tick, Packet(Arc), - /// Happens when a player is added, removed, or updated in the tab list. - UpdatePlayers(UpdatePlayersEvent), - /// Emits when the player dies. + /// A player joined the game (or more specifically, was added to the tab + /// list). + AddPlayer(PlayerInfo), + /// A player left the game (or maybe is still in the game and was just + /// removed from the tab list). + RemovePlayer(PlayerInfo), + /// A player was updated in the tab list (gamemode, display + /// name, or latency changed). + UpdatePlayer(PlayerInfo), + /// The client player died in-game. Death(Option>), } -/// Happens when a player is added, removed, or updated in the tab list. -#[derive(Debug, Clone)] -pub enum UpdatePlayersEvent { - /// A player with the given info was added to the tab list (usually means - /// they joined the server). - Add(PlayerInfo), - /// A player with the given UUID was removed from the tab list (usually - /// means they left the server) - Remove { uuid: Uuid }, - /// The latency of the player with the given UUID was updated in the tab - /// list. Note that this can be spoofed by the player and may not represent - /// their actual latency. - Latency { - uuid: Uuid, - /// The time it took in milliseconds for this player to reply to the ping packet. - latency: i32, - }, - /// The played switched to a different gamemode (i.e. survival, creative, spectator) - GameMode { uuid: Uuid, game_mode: GameType }, - /// The name of the player with the given UUID in the tab list was changed or reset. - DisplayName { - uuid: Uuid, - display_name: Option, - }, -} - /// A player that you control that is currently in a Minecraft server. #[derive(Clone)] pub struct Client { @@ -141,6 +127,7 @@ pub struct PhysicsState { /// Whether we should ignore errors when decoding packets. const IGNORE_ERRORS: bool = !cfg!(debug_assertions); +/// An error that happened while joining the server. #[derive(Error, Debug)] pub enum JoinError { #[error("{0}")] @@ -148,7 +135,7 @@ pub enum JoinError { #[error("{0}")] Connection(#[from] ConnectionError), #[error("{0}")] - ReadPacket(#[from] azalea_protocol::read::ReadPacketError), + ReadPacket(#[from] Box), #[error("{0}")] Io(#[from] io::Error), #[error("{0}")] @@ -280,8 +267,7 @@ impl Client { // login conn.write( ServerboundHelloPacket { - username: account.username.clone(), - public_key: None, + name: account.username.clone(), profile_id: None, } .get(), @@ -309,8 +295,8 @@ impl Client { conn.write( ServerboundKeyPacket { - nonce_or_salt_signature: NonceOrSaltSignature::Nonce(e.encrypted_nonce), key_bytes: e.encrypted_public_key, + encrypted_challenge: e.encrypted_nonce, } .get(), ) @@ -396,6 +382,7 @@ impl Client { } }, Err(e) => { + let e = *e; if let ReadPacketError::ConnectionClosed = e { info!("Connection closed"); if let Err(e) = client.disconnect().await { @@ -403,13 +390,19 @@ impl Client { } break; } + let default_backtrace = Backtrace::capture(); if IGNORE_ERRORS { - warn!("{}", e); - if let ReadPacketError::FrameSplitter { .. } = e { - panic!("Error: {e:?}"); + let backtrace = + any::request_ref::(&e).unwrap_or(&default_backtrace); + warn!("{e}\n{backtrace}"); + match e { + ReadPacketError::FrameSplitter { .. } => panic!("Error: {e:?}"), + _ => continue, } } else { - panic!("{}", e); + let backtrace = + any::request_ref::(&e).unwrap_or(&default_backtrace); + panic!("{e}\n{backtrace}") } } }; @@ -657,100 +650,56 @@ impl Client { ) .await?; } - ClientboundGamePacket::PlayerInfo(p) => { - use azalea_protocol::packets::game::clientbound_player_info_packet::Action; - + ClientboundGamePacket::PlayerInfoUpdate(p) => { debug!("Got player info packet {:?}", p); let mut events = Vec::new(); { let mut players_lock = client.players.write(); - match &p.action { - Action::AddPlayer(players) => { - for player in players { - let player_info = PlayerInfo { - profile: GameProfile { - uuid: player.uuid, - name: player.name.clone(), - properties: player.properties.clone(), - }, - uuid: player.uuid, - gamemode: player.gamemode, - latency: player.latency, - display_name: player.display_name.clone(), - }; - players_lock.insert(player.uuid, player_info.clone()); - events.push(Event::UpdatePlayers(UpdatePlayersEvent::Add( - player_info, - ))); + for updated_info in &p.entries { + // add the new player maybe + if p.actions.add_player { + let player_info = PlayerInfo { + profile: updated_info.profile.clone(), + uuid: updated_info.profile.uuid, + gamemode: updated_info.game_mode, + latency: updated_info.latency, + display_name: updated_info.display_name.clone(), + }; + players_lock.insert(updated_info.profile.uuid, player_info.clone()); + events.push(Event::AddPlayer(player_info)); + } else if let Some(info) = players_lock.get_mut(&updated_info.profile.uuid) + { + // `else if` because the block for add_player above + // already sets all the fields + if p.actions.update_game_mode { + info.gamemode = updated_info.game_mode; } - } - Action::UpdateGameMode(players) => { - for player in players { - if let Some(p) = players_lock.get_mut(&player.uuid) { - p.gamemode = player.gamemode; - events.push(Event::UpdatePlayers( - UpdatePlayersEvent::GameMode { - uuid: player.uuid, - game_mode: player.gamemode, - }, - )); - } else { - warn!( - "Ignoring PlayerInfo (UpdateGameMode) for unknown player {}", - player.uuid - ); - } + if p.actions.update_latency { + info.latency = updated_info.latency; } - } - Action::UpdateLatency(players) => { - for player in players { - if let Some(p) = players_lock.get_mut(&player.uuid) { - p.latency = player.latency; - events.push(Event::UpdatePlayers( - UpdatePlayersEvent::Latency { - uuid: player.uuid, - latency: player.latency, - }, - )); - } else { - warn!( - "Ignoring PlayerInfo (UpdateLatency) for unknown player {}", - player.uuid - ); - } - } - } - Action::UpdateDisplayName(players) => { - for player in players { - if let Some(p) = players_lock.get_mut(&player.uuid) { - p.display_name = player.display_name.clone(); - events.push(Event::UpdatePlayers( - UpdatePlayersEvent::DisplayName { - uuid: player.uuid, - display_name: player.display_name.clone(), - }, - )); - } else { - warn!( - "Ignoring PlayerInfo (UpdateDisplayName) for unknown player {}", - player.uuid - ); - } + if p.actions.update_display_name { + info.display_name = updated_info.display_name.clone(); } + events.push(Event::UpdatePlayer(info.clone())); + } else { + warn!( + "Ignoring PlayerInfoUpdate for unknown player {}", + updated_info.profile.uuid + ); } - Action::RemovePlayer(players) => { - for player in players { - if players_lock.remove(&player.uuid).is_some() { - events.push(Event::UpdatePlayers(UpdatePlayersEvent::Remove { - uuid: player.uuid, - })); - } else { - warn!( - "Ignoring PlayerInfo (RemovePlayer) for unknown player {}", - player.uuid - ); - } - } + } + } + for event in events { + tx.send(event).await?; + } + } + ClientboundGamePacket::PlayerInfoRemove(p) => { + let mut events = Vec::new(); + { + let mut players_lock = client.players.write(); + for uuid in &p.profile_ids { + if let Some(info) = players_lock.remove(uuid) { + events.push(Event::RemovePlayer(info)); } } } @@ -948,13 +897,11 @@ impl Client { ClientboundGamePacket::BlockEntityData(_) => {} ClientboundGamePacket::BlockEvent(_) => {} ClientboundGamePacket::BossEvent(_) => {} - ClientboundGamePacket::ChatPreview(_) => {} ClientboundGamePacket::CommandSuggestions(_) => {} ClientboundGamePacket::ContainerSetData(_) => {} ClientboundGamePacket::ContainerSetSlot(_) => {} ClientboundGamePacket::Cooldown(_) => {} ClientboundGamePacket::CustomChatCompletions(_) => {} - ClientboundGamePacket::CustomSound(_) => {} ClientboundGamePacket::DeleteChat(_) => {} ClientboundGamePacket::Explode(_) => {} ClientboundGamePacket::ForgetLevelChunk(_) => {} @@ -967,7 +914,6 @@ impl Client { ClientboundGamePacket::OpenSignEditor(_) => {} ClientboundGamePacket::Ping(_) => {} ClientboundGamePacket::PlaceGhostRecipe(_) => {} - ClientboundGamePacket::PlayerChatHeader(_) => {} ClientboundGamePacket::PlayerCombatEnd(_) => {} ClientboundGamePacket::PlayerCombatEnter(_) => {} ClientboundGamePacket::PlayerCombatKill(p) => { @@ -998,7 +944,6 @@ impl Client { ClientboundGamePacket::SetBorderWarningDelay(_) => {} ClientboundGamePacket::SetBorderWarningDistance(_) => {} ClientboundGamePacket::SetCamera(_) => {} - ClientboundGamePacket::SetDisplayChatPreview(_) => {} ClientboundGamePacket::SetDisplayObjective(_) => {} ClientboundGamePacket::SetObjective(_) => {} ClientboundGamePacket::SetPassengers(_) => {} @@ -1013,6 +958,8 @@ impl Client { ClientboundGamePacket::TabList(_) => {} ClientboundGamePacket::TagQuery(_) => {} ClientboundGamePacket::TakeItemEntity(_) => {} + ClientboundGamePacket::DisguisedChat(_) => {} + ClientboundGamePacket::UpdateEnabledFeatures(_) => {} ClientboundGamePacket::ContainerClose(_) => {} } diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index 91c8cd91..f2952248 100644 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -2,13 +2,13 @@ //! real clients. If you want to make bots, you should use the //! [`azalea`] crate instead. //! -//! [`azalea_protocol`]: https://crates.io/crates/azalea-protocol -//! [`azalea`]: https://crates.io/crates/azalea +//! [`azalea_protocol`]: https://docs.rs/azalea-protocol +//! [`azalea`]: https://docs.rs/azalea +#![feature(provide_any)] #![allow(incomplete_features)] #![feature(trait_upcasting)] #![feature(error_generic_member_access)] -#![feature(provide_any)] mod account; mod chat; diff --git a/azalea-client/src/ping.rs b/azalea-client/src/ping.rs index 289622b6..8acde7a5 100755 --- a/azalea-client/src/ping.rs +++ b/azalea-client/src/ping.rs @@ -23,7 +23,7 @@ pub enum PingError { #[error("{0}")] Connection(#[from] ConnectionError), #[error("{0}")] - ReadPacket(#[from] azalea_protocol::read::ReadPacketError), + ReadPacket(#[from] Box), #[error("{0}")] WritePacket(#[from] io::Error), #[error("The given address could not be parsed into a ServerAddress")] -- cgit v1.2.3