diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-10-16 23:08:39 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-16 23:08:39 -0500 |
| commit | 0f88e05a0cfe43c910f130f8e70f51055d9f6fd2 (patch) | |
| tree | dd1b899c7b90ae80b13bb0c84b44615dde63c7b1 | |
| parent | ab9e50b1307012b698d826a1f4d04b347ee2203f (diff) | |
| download | azalea-drasl-0f88e05a0cfe43c910f130f8e70f51055d9f6fd2.tar.xz | |
Add chat function (#28)
* add Client::chat
* make the default bot do chat
| -rw-r--r-- | azalea-client/src/chat.rs | 74 | ||||
| -rwxr-xr-x | azalea-client/src/lib.rs | 1 | ||||
| -rw-r--r-- | azalea-crypto/src/signing.rs | 5 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs | 2 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs | 2 | ||||
| -rw-r--r-- | bot/src/main.rs | 12 |
6 files changed, 91 insertions, 5 deletions
diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs new file mode 100644 index 00000000..6176357f --- /dev/null +++ b/azalea-client/src/chat.rs @@ -0,0 +1,74 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + +use azalea_crypto::MessageSignature; +use azalea_protocol::packets::game::{ + clientbound_player_chat_packet::LastSeenMessagesUpdate, + serverbound_chat_command_packet::ServerboundChatCommandPacket, + serverbound_chat_packet::ServerboundChatPacket, +}; + +use crate::Client; + +impl Client { + /// Sends chat message to the server. This only sends the chat packet and + /// not the command packet. The `chat` function handles checking whether + /// the message is a command and using the proper packet for you. + pub async fn send_chat_packet(&self, message: &str) -> Result<(), std::io::Error> { + // TODO: chat signing + let signature = sign_message(); + let packet = ServerboundChatPacket { + message: message.to_string(), + timestamp: SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time shouldn't be before epoch") + .as_millis() + .try_into() + .expect("Instant should fit into a u64"), + salt: azalea_crypto::make_salt(), + signature, + signed_preview: false, + last_seen_messages: LastSeenMessagesUpdate::default(), + } + .get(); + self.write_packet(packet).await + } + + /// Send a command packet to the server. The `command` argument should not + /// include the slash at the front. + pub async fn send_command_packet(&self, command: &str) -> Result<(), std::io::Error> { + // TODO: chat signing + let packet = ServerboundChatCommandPacket { + command: command.to_string(), + timestamp: SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time shouldn't be before epoch") + .as_millis() + .try_into() + .expect("Instant should fit into a u64"), + salt: azalea_crypto::make_salt(), + argument_signatures: vec![], + signed_preview: false, + last_seen_messages: LastSeenMessagesUpdate::default(), + } + .get(); + self.write_packet(packet).await + } + + pub async fn chat(&self, message: &str) -> Result<(), std::io::Error> { + if message.chars().next() == Some('/') { + self.send_command_packet(&message[1..]).await + } else { + 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() +} diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index c30ca103..1ed30394 100755 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -1,6 +1,7 @@ //! Significantly abstract azalea-protocol so it's actually useable for bots. mod account; +mod chat; mod client; mod get_mc_dir; mod movement; diff --git a/azalea-crypto/src/signing.rs b/azalea-crypto/src/signing.rs index 3bad08c9..7df0963b 100644 --- a/azalea-crypto/src/signing.rs +++ b/azalea-crypto/src/signing.rs @@ -17,3 +17,8 @@ pub struct SignedMessageHeader { pub previous_signature: Option<MessageSignature>, pub sender: Uuid, } + +/// Generates a random u64 to use as a salt +pub fn make_salt() -> u64 { + rand::random() +} 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 c6013fc2..e961828e 100644 --- a/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_player_chat_packet.rs @@ -68,7 +68,7 @@ pub struct LastSeenMessagesEntry { pub last_signature: MessageSignature, } -#[derive(Clone, Debug, McBuf)] +#[derive(Clone, Debug, McBuf, Default)] pub struct LastSeenMessagesUpdate { pub last_seen: Vec<LastSeenMessagesEntry>, pub last_received: Option<LastSeenMessagesEntry>, diff --git a/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs b/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs index 426ca882..a840e44f 100644 --- a/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs +++ b/azalea-protocol/src/packets/game/serverbound_chat_command_packet.rs @@ -9,7 +9,7 @@ pub struct ServerboundChatCommandPacket { pub command: String, // TODO: Choose a real timestamp type pub timestamp: u64, - pub salt: i64, + pub salt: u64, pub argument_signatures: Vec<ArgumentSignature>, pub signed_preview: bool, pub last_seen_messages: LastSeenMessagesUpdate, diff --git a/bot/src/main.rs b/bot/src/main.rs index 92786ce1..beed4320 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -10,7 +10,7 @@ struct State {} async fn main() -> anyhow::Result<()> { env_logger::init(); - let account = Account::microsoft("example2@example.com").await?; + let account = Account::microsoft("example@example.com").await?; azalea::start(azalea::Options { account, @@ -26,8 +26,14 @@ async fn main() -> anyhow::Result<()> { } async fn handle(bot: Client, event: Arc<Event>, _state: Arc<Mutex<State>>) -> anyhow::Result<()> { - if let Event::Tick = *event { - bot.jump(); + match *event { + Event::Login => { + bot.chat("Hello world").await?; + } + Event::Tick => { + bot.jump(); + } + _ => {} } Ok(()) |
