From 1a626da9ba1017d0575e4a613bc2eee944e5d37e Mon Sep 17 00:00:00 2001 From: mat Date: Mon, 24 Oct 2022 21:35:54 -0500 Subject: [PATCH] add more stuff to clientbound player chat packet --- azalea-client/src/chat.rs | 4 - azalea-client/src/client.rs | 26 +++-- azalea-physics/src/lib.rs | 10 +- azalea-protocol/src/lib.rs | 4 +- .../game/clientbound_disguised_chat_packet.rs | 5 +- .../game/clientbound_player_chat_packet.rs | 104 +++++++++++++++++- .../packets/login/serverbound_hello_packet.rs | 4 +- codegen/migrate.py | 1 + 8 files changed, 126 insertions(+), 32 deletions(-) diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index 18fa4549..15d2e933 100644 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -90,10 +90,6 @@ 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 diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 60f9c9fc..97f3d5dd 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -17,7 +17,7 @@ use azalea_protocol::{ }, handshake::client_intention_packet::ClientIntentionPacket, login::{ - serverbound_hello_packet::ServerboundHelloPacket, + serverbound_hello_packet::{RemoteChatSessionData, ServerboundHelloPacket}, serverbound_key_packet::{NonceOrSaltSignature, ServerboundKeyPacket}, ClientboundLoginPacket, }, @@ -43,6 +43,7 @@ use tokio::{ task::JoinHandle, time::{self}, }; +use uuid::Uuid; pub type ClientInformation = ServerboundClientInformationPacket; @@ -72,7 +73,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(), } } } @@ -173,8 +174,11 @@ impl Client { // login conn.write( ServerboundHelloPacket { - username: account.username.clone(), - public_key: None, + name: account.username.clone(), + chat_session: RemoteChatSessionData { + session_id: Uuid::nil(), + profile_public_key: None, + }, profile_id: None, } .get(), @@ -422,8 +426,8 @@ impl Client { tx.send(Event::Login).unwrap(); } - ClientboundGamePacket::UpdateViewDistance(p) => { - debug!("Got view distance packet {:?}", p); + ClientboundGamePacket::SetChunkCacheRadius(p) => { + debug!("Got set chunk cache radius packet {:?}", p); } ClientboundGamePacket::CustomPayload(p) => { debug!("Got custom payload packet {:?}", p); @@ -546,7 +550,7 @@ impl Client { ) .await?; } - ClientboundGamePacket::PlayerInfo(p) => { + ClientboundGamePacket::PlayerInfoUpdate(p) => { debug!("Got player info packet {:?}", p); } ClientboundGamePacket::SetChunkCacheCenter(p) => { @@ -581,7 +585,7 @@ impl Client { ClientboundGamePacket::UpdateAttributes(_p) => { // debug!("Got update attributes packet {:?}", p); } - ClientboundGamePacket::EntityVelocity(_p) => { + ClientboundGamePacket::SetEntityMotion(_p) => { // debug!("Got entity velocity packet {:?}", p); } ClientboundGamePacket::SetEntityLink(p) => { @@ -708,7 +712,6 @@ impl Client { ClientboundGamePacket::BlockEntityData(_) => {} ClientboundGamePacket::BlockEvent(_) => {} ClientboundGamePacket::BossEvent(_) => {} - ClientboundGamePacket::ChatPreview(_) => {} ClientboundGamePacket::CommandSuggestions(_) => {} ClientboundGamePacket::ContainerSetData(_) => {} ClientboundGamePacket::ContainerSetSlot(_) => {} @@ -727,7 +730,6 @@ impl Client { ClientboundGamePacket::OpenSignEditor(_) => {} ClientboundGamePacket::Ping(_) => {} ClientboundGamePacket::PlaceGhostRecipe(_) => {} - ClientboundGamePacket::PlayerChatHeader(_) => {} ClientboundGamePacket::PlayerCombatEnd(_) => {} ClientboundGamePacket::PlayerCombatEnter(_) => {} ClientboundGamePacket::PlayerCombatKill(_) => {} @@ -744,7 +746,6 @@ impl Client { ClientboundGamePacket::SetBorderWarningDistance(_) => {} ClientboundGamePacket::SetCamera(_) => {} ClientboundGamePacket::SetChunkCacheRadius(_) => {} - ClientboundGamePacket::SetDisplayChatPreview(_) => {} ClientboundGamePacket::SetDisplayObjective(_) => {} ClientboundGamePacket::SetEntityMotion(_) => {} ClientboundGamePacket::SetObjective(_) => {} @@ -760,6 +761,9 @@ impl Client { ClientboundGamePacket::TabList(_) => {} ClientboundGamePacket::TagQuery(_) => {} ClientboundGamePacket::TakeItemEntity(_) => {} + ClientboundGamePacket::DisguisedChat(_) => {} + ClientboundGamePacket::PlayerInfoRemove(_) => {} + ClientboundGamePacket::UpdateEnabledFeatures(_) => {} } Ok(()) diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs index ac0b92a8..cf641519 100644 --- a/azalea-physics/src/lib.rs +++ b/azalea-physics/src/lib.rs @@ -233,7 +233,7 @@ mod tests { dim.add_entity( 0, EntityData::new( - Uuid::from_u128(0), + Uuid::nil(), Vec3 { x: 0., y: 70., @@ -264,7 +264,7 @@ mod tests { dim.add_entity( 0, EntityData::new( - Uuid::from_u128(0), + Uuid::nil(), Vec3 { x: 0.5, y: 70., @@ -295,7 +295,7 @@ mod tests { dim.add_entity( 0, EntityData::new( - Uuid::from_u128(0), + Uuid::nil(), Vec3 { x: 0.5, y: 71., @@ -327,7 +327,7 @@ mod tests { dim.add_entity( 0, EntityData::new( - Uuid::from_u128(0), + Uuid::nil(), Vec3 { x: 0.5, y: 71., @@ -359,7 +359,7 @@ mod tests { dim.add_entity( 0, EntityData::new( - Uuid::from_u128(0), + Uuid::nil(), Vec3 { x: 0.5, y: 73., diff --git a/azalea-protocol/src/lib.rs b/azalea-protocol/src/lib.rs index ab447210..f1f865d1 100755 --- a/azalea-protocol/src/lib.rs +++ b/azalea-protocol/src/lib.rs @@ -87,7 +87,7 @@ mod tests { key: b"idontthinkthisreallymattersijustwantittobelongforthetest".to_vec(), key_signature: b"idontthinkthisreallymattersijustwantittobelongforthetest".to_vec(), }), - profile_id: Some(Uuid::from_u128(0)), + profile_id: Some(Uuid::nil()), } .get(); let mut stream = Vec::new(); @@ -116,7 +116,7 @@ mod tests { key: b"idontthinkthisreallymattersijustwantittobelongforthetest".to_vec(), key_signature: b"idontthinkthisreallymattersijustwantittobelongforthetest".to_vec(), }), - profile_id: Some(Uuid::from_u128(0)), + profile_id: Some(Uuid::nil()), } .get(); let mut stream = Vec::new(); diff --git a/azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs index c0c1b195..5601fc67 100644 --- a/azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_disguised_chat_packet.rs @@ -1,3 +1,4 @@ +use super::clientbound_player_chat_packet::ChatTypeBound; use azalea_buf::McBuf; use azalea_chat::component::Component; use azalea_protocol_macros::ClientboundGamePacket; @@ -5,7 +6,5 @@ use azalea_protocol_macros::ClientboundGamePacket; #[derive(Clone, Debug, McBuf, ClientboundGamePacket)] pub struct ClientboundDisguisedChatPacket { pub message: Component, - // TODO: {'field': 'b.a', 'operation': 'write', 'type': 'varint'} - // TODO: {'field': 'b.b', 'operation': 'write', 'type': 'chatcomponent'} - pub chat_type: Option, + pub chat_type: ChatTypeBound, } diff --git a/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs b/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs index 52c85f4f..20923f79 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs @@ -1,7 +1,10 @@ use azalea_buf::{ BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, }; -use azalea_chat::component::Component; +use azalea_chat::{ + component::Component, + translatable_component::{StringOrComponent, TranslatableComponent}, +}; use azalea_core::BitSet; use azalea_crypto::MessageSignature; use azalea_protocol_macros::ClientboundGamePacket; @@ -17,7 +20,7 @@ pub struct ClientboundPlayerChatPacket { pub body: PackedSignedMessageBody, pub unsigned_content: Option, pub filter_mask: FilterMask, - pub chat_type: Option, + pub chat_type: ChatTypeBound, } #[derive(Clone, Debug, McBuf)] @@ -47,6 +50,97 @@ pub enum FilterMask { PartiallyFiltered(BitSet), } +#[derive(Copy, Clone, Debug, McBuf, PartialEq, Eq)] +pub enum ChatType { + Chat = 0, + SayCommand = 1, + MsgCommandIncoming = 2, + MsgCommandOutgoing = 3, + TeamMsgCommandIncoming = 4, + TeamMsgCommandOutgoing = 5, + EmoteCommand = 6, +} + +#[derive(Clone, Debug, McBuf)] +pub struct ChatTypeBound { + pub chat_type: ChatType, + pub name: Component, + pub target_name: Option, +} + +// must be in Client +pub struct MessageSignatureCache { + pub entries: Vec>, +} + +// impl MessageSignatureCache { +// pub fn unpacker(&self) -> impl Fn(u32) -> Option { + +// } +// } + +// impl PackedSignedMessageBody { +// pub fn unpack(&self, unpacker: impl Fn(u32) -> Option) {} +// } + +impl ClientboundPlayerChatPacket { + /// Returns the content of the message. If you want to get the Component + /// for the whole message including the sender part, use + /// [`ClientboundPlayerChatPacket::message`]. + pub fn content(&self) -> Component { + self.unsigned_content + .clone() + .unwrap_or_else(|| Component::from(self.body.content.clone())) + } + + /// Get the full message, including the sender part. + pub fn message(&self) -> Component { + let sender = self.chat_type.name.clone(); + let content = self.content(); + let target = self.chat_type.target_name.clone(); + + let translation_key = self.chat_type.chat_type.chat_translation_key(); + + let mut args = vec![ + StringOrComponent::Component(sender), + StringOrComponent::Component(content), + ]; + if let Some(target) = target { + args.push(StringOrComponent::Component(target)); + } + + let component = TranslatableComponent::new(translation_key.to_string(), args); + + Component::Translatable(component) + } +} + +impl ChatType { + pub fn chat_translation_key(&self) -> &'static str { + match self { + ChatType::Chat => "chat.type.text", + ChatType::SayCommand => "chat.type.announcement", + ChatType::MsgCommandIncoming => "commands.message.display.incoming", + ChatType::MsgCommandOutgoing => "commands.message.display.outgoing", + ChatType::TeamMsgCommandIncoming => "chat.type.team.text", + ChatType::TeamMsgCommandOutgoing => "chat.type.team.sent", + ChatType::EmoteCommand => "chat.type.emote", + } + } + + pub fn narrator_translation_key(&self) -> &'static str { + match self { + ChatType::Chat => "chat.type.text.narrate", + ChatType::SayCommand => "chat.type.text.narrate", + ChatType::MsgCommandIncoming => "chat.type.text.narrate", + ChatType::MsgCommandOutgoing => "chat.type.text.narrate", + ChatType::TeamMsgCommandIncoming => "chat.type.text.narrate", + ChatType::TeamMsgCommandOutgoing => "chat.type.text.narrate", + ChatType::EmoteCommand => "chat.type.emote", + } + } +} + impl McBufReadable for PackedMessageSignature { fn read_from(buf: &mut Cursor<&[u8]>) -> Result { let id = u32::var_read_from(buf)?; @@ -62,11 +156,11 @@ impl McBufWritable for PackedMessageSignature { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { match self { PackedMessageSignature::Signature(full_signature) => { - 0u32.var_write_into(buf); - full_signature.write_into(buf); + 0u32.var_write_into(buf)?; + full_signature.write_into(buf)?; } PackedMessageSignature::Id(id) => { - (id + 1).var_write_into(buf); + (id + 1).var_write_into(buf)?; } } Ok(()) diff --git a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs index 4da0de3b..b7f9794b 100755 --- a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs +++ b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs @@ -34,10 +34,10 @@ mod tests { let packet = ServerboundHelloPacket { name: "test".to_string(), chat_session: RemoteChatSessionData { - session_id: Uuid::default(), + session_id: Uuid::nil(), profile_public_key: None, }, - profile_id: Some(Uuid::from_u128(0)), + profile_id: Some(Uuid::nil()), }; let mut buf: Vec = Vec::new(); packet.write_into(&mut buf).unwrap(); diff --git a/codegen/migrate.py b/codegen/migrate.py index 50bdb354..0175a285 100644 --- a/codegen/migrate.py +++ b/codegen/migrate.py @@ -120,3 +120,4 @@ if old_ordered_blocks != new_ordered_blocks: lib.code.utils.fmt() print('Done!') +print('Make sure to `cargo check` and look for the generated `TODO`s to make sure everything is correct!')