mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
add more stuff to clientbound player chat packet
This commit is contained in:
parent
acc73ae406
commit
1a626da9ba
8 changed files with 126 additions and 32 deletions
|
@ -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
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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.,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<Component>,
|
||||
pub chat_type: ChatTypeBound,
|
||||
}
|
||||
|
|
|
@ -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<Component>,
|
||||
pub filter_mask: FilterMask,
|
||||
pub chat_type: Option<Component>,
|
||||
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<Component>,
|
||||
}
|
||||
|
||||
// must be in Client
|
||||
pub struct MessageSignatureCache {
|
||||
pub entries: Vec<Option<MessageSignature>>,
|
||||
}
|
||||
|
||||
// impl MessageSignatureCache {
|
||||
// pub fn unpacker(&self) -> impl Fn(u32) -> Option<SignedMessageBody> {
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl PackedSignedMessageBody {
|
||||
// pub fn unpack(&self, unpacker: impl Fn(u32) -> Option<SignedMessageBody>) {}
|
||||
// }
|
||||
|
||||
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<Self, BufReadError> {
|
||||
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(())
|
||||
|
|
|
@ -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<u8> = Vec::new();
|
||||
packet.write_into(&mut buf).unwrap();
|
||||
|
|
|
@ -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!')
|
||||
|
|
Loading…
Add table
Reference in a new issue