diff --git a/pumpkin-protocol/src/client/play/c_player_chat_message.rs b/pumpkin-protocol/src/client/play/c_player_chat_message.rs index ade16d85..03f2160b 100644 --- a/pumpkin-protocol/src/client/play/c_player_chat_message.rs +++ b/pumpkin-protocol/src/client/play/c_player_chat_message.rs @@ -1,11 +1,11 @@ use num_derive::{FromPrimitive, ToPrimitive}; +use num_traits::FromPrimitive; use pumpkin_macros::packet; use pumpkin_text::TextComponent; use serde::Serialize; -use crate::{uuid::UUID, BitSet, VarInt}; +use crate::{bytebuf::ByteBuffer, uuid::UUID, BitSet, ClientPacket, VarInt}; -#[derive(Serialize)] #[packet(0x39)] pub struct CPlayerChatMessage<'a> { sender: UUID, @@ -19,6 +19,9 @@ pub struct CPlayerChatMessage<'a> { unsigned_content: Option>, /// See `FilterType` filter_type: VarInt, + + // TODO: Implement + #[allow(dead_code)] filter_type_bits: Option>, chat_type: VarInt, sender_name: TextComponent<'a>, @@ -61,6 +64,52 @@ impl<'a> CPlayerChatMessage<'a> { } } +impl<'a> ClientPacket for CPlayerChatMessage<'a> { + fn write(&self, bytebuf: &mut ByteBuffer) { + bytebuf.put_uuid(self.sender.0); + bytebuf.put_var_int(&self.index); + bytebuf.put_option(&self.message_signature, |p, v| p.put_slice(v)); + bytebuf.put_string(self.message); + bytebuf.put_i64(self.timestamp); + bytebuf.put_i64(self.salt); + + if self.previous_messages_count.0 > 20 { + // TODO: Assert this is <=20 + } + + bytebuf.put_var_int(&self.previous_messages_count); + for previous_message in self.previous_messages { + bytebuf.put_var_int(&previous_message.message_id); + if let Some(prev_sig) = previous_message.signature { + // TODO: validate whether this should be None or not + bytebuf.put_slice(prev_sig); + } + } + + bytebuf.put_option(&self.unsigned_content, |p, v| { + p.put_slice(v.encode().as_slice()) + }); + + bytebuf.put_var_int(&self.filter_type); + match FilterType::from_i32(self.filter_type.0) { + Some(FilterType::PassThrough) => (), + Some(FilterType::FullyFiltered) => { + // TODO: Implement + } + Some(FilterType::PartiallyFiltered) => { + // TODO: Implement + } + None => { + // TODO: Implement + } + } + + bytebuf.put_var_int(&self.chat_type); + bytebuf.put_slice(self.sender_name.encode().as_slice()); + bytebuf.put_option(&self.target_name, |p, v| p.put_slice(v.encode().as_slice())); + } +} + #[derive(Serialize)] pub struct PreviousMessage<'a> { message_id: VarInt, diff --git a/pumpkin-protocol/src/server/play/s_chat_message.rs b/pumpkin-protocol/src/server/play/s_chat_message.rs index c0a98964..fc153094 100644 --- a/pumpkin-protocol/src/server/play/s_chat_message.rs +++ b/pumpkin-protocol/src/server/play/s_chat_message.rs @@ -14,6 +14,7 @@ pub struct SChatMessage { pub salt: i64, pub signature: Option, pub messagee_count: VarInt, + // TODO: Properly implement BitSet decoding // acknowledged: BitSet, } @@ -24,7 +25,7 @@ impl ServerPacket for SChatMessage { message: bytebuf.get_string().unwrap(), timestamp: bytebuf.get_i64(), salt: bytebuf.get_i64(), - signature: bytebuf.get_option(|v| v.copy_to_bytes(255)), + signature: bytebuf.get_option(|v| v.copy_to_bytes(256)), messagee_count: bytebuf.get_var_int(), }) }