aboutsummaryrefslogtreecommitdiff
path: root/azalea-client
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2022-12-07 21:09:58 -0600
committerGitHub <noreply@github.com>2022-12-07 21:09:58 -0600
commit7d901e39bc10a855b545d7b6c167f45148a1fb0a (patch)
tree88fe0a8f2f04f49f4df90e2f5462aa35a4278c68 /azalea-client
parent9f5e5c092be9167e4d5222fdee4a1d2c419e5052 (diff)
downloadazalea-drasl-7d901e39bc10a855b545d7b6c167f45148a1fb0a.tar.xz
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
Diffstat (limited to 'azalea-client')
-rwxr-xr-xazalea-client/src/chat.rs25
-rw-r--r--azalea-client/src/client.rs213
-rw-r--r--azalea-client/src/lib.rs6
-rwxr-xr-xazalea-client/src/ping.rs2
4 files changed, 93 insertions, 153 deletions
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<ClientboundGamePacket>),
- /// 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<Arc<ClientboundPlayerCombatKillPacket>>),
}
-/// 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<Component>,
- },
-}
-
/// 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<azalea_protocol::read::ReadPacketError>),
#[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::<Backtrace>(&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::<Backtrace>(&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<azalea_protocol::read::ReadPacketError>),
#[error("{0}")]
WritePacket(#[from] io::Error),
#[error("The given address could not be parsed into a ServerAddress")]