diff --git a/Cargo.lock b/Cargo.lock index 67259fef..8d94c26c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,6 +117,7 @@ dependencies = [ "async-recursion", "async-trait", "azalea-auth", + "azalea-brigadier", "azalea-chat", "azalea-core", "azalea-nbt", diff --git a/README.md b/README.md index 3ae4b307..ed6ed46f 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ I named this Azalea because it sounds like a cool word and this is a cool librar ## Goals -- Bypass most anticheats -- Only support the latest Minecraft version - Do everything a vanilla client can do -- Be fast - Be easy to use +- Bypass most/all anticheats +- Support the latest Minecraft version +- Be fast diff --git a/azalea-client/src/connect.rs b/azalea-client/src/connect.rs index 7b1da525..bc45a121 100644 --- a/azalea-client/src/connect.rs +++ b/azalea-client/src/connect.rs @@ -73,6 +73,9 @@ pub async fn join_server(address: &ServerAddress) -> Result<(), String> { GamePacket::ClientboundChangeDifficultyPacket(p) => { println!("Got difficulty packet {:?}", p); } + GamePacket::ClientboundDeclareCommandsPacket(p) => { + println!("Got declare commands packet {:?}", p); + } }, Err(e) => { println!("Error: {:?}", e); diff --git a/azalea-protocol/Cargo.toml b/azalea-protocol/Cargo.toml index ff3bd9d4..37df8697 100644 --- a/azalea-protocol/Cargo.toml +++ b/azalea-protocol/Cargo.toml @@ -10,6 +10,7 @@ async-compression = {version = "^0.3.8", features = ["tokio", "zlib"]} async-recursion = "^0.3.2" async-trait = "0.1.51" azalea-auth = {path = "../azalea-auth"} +azalea-brigadier = {path = "../azalea-brigadier"} azalea-chat = {path = "../azalea-chat"} azalea-core = {path = "../azalea-core"} azalea-nbt = {path = "../azalea-nbt"} diff --git a/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs b/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs index 1bcf0dd4..1403630d 100644 --- a/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_declare_commands_packet.rs @@ -1,37 +1,96 @@ -// use std::hash::Hash; +use std::hash::Hash; -// use crate::mc_buf::Readable; +use async_trait::async_trait; +use tokio::io::AsyncRead; -// use super::LoginPacket; +use crate::mc_buf::{McBufReadable, Readable}; -// #[derive(Hash, Clone, Debug)] -// pub struct ClientboundDeclareCommandsPacket { -// pub root: RootCommandNode, -// pub public_key: Vec, -// pub nonce: Vec, -// } +use super::GamePacket; -// impl ClientboundHelloPacket { -// pub fn get(self) -> LoginPacket { -// LoginPacket::ClientboundHelloPacket(self) -// } +#[derive(Hash, Clone, Debug)] +pub struct ClientboundDeclareCommandsPacket { + pub entries: Vec, + pub root_index: i32, +} -// pub fn write(&self, _buf: &mut Vec) -> Result<(), std::io::Error> { -// panic!("ClientboundHelloPacket::write not implemented") -// } +impl ClientboundDeclareCommandsPacket { + pub fn get(self) -> GamePacket { + GamePacket::ClientboundDeclareCommandsPacket(self) + } -// pub async fn read( -// buf: &mut T, -// ) -> Result { -// let server_id = buf.read_utf_with_len(20).await?; -// let public_key = buf.read_byte_array().await?; -// let nonce = buf.read_byte_array().await?; + pub fn write(&self, _buf: &mut Vec) -> Result<(), std::io::Error> { + panic!("ClientboundDeclareCommandsPacket::write not implemented") + } -// Ok(ClientboundHelloPacket { -// server_id, -// public_key, -// nonce, -// } -// .get()) -// } -// } + pub async fn read( + buf: &mut T, + ) -> Result { + let node_count = buf.read_varint().await?; + println!("node_count: {}", node_count); + let mut nodes = Vec::with_capacity(node_count as usize); + for _ in 0..node_count { + let node = BrigadierNodeStub::read_into(buf).await?; + nodes.push(node); + } + let root_index = buf.read_varint().await?; + Ok(GamePacket::ClientboundDeclareCommandsPacket( + ClientboundDeclareCommandsPacket { + entries: nodes, + root_index, + }, + )) + } +} + +#[derive(Hash, Debug, Clone)] +pub struct BrigadierNodeStub {} + +// azalea_brigadier::tree::CommandNode +#[async_trait] +impl McBufReadable for BrigadierNodeStub { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + let flags = u8::read_into(buf).await?; + + let node_type = flags & 0x03; + let is_executable = flags & 0x04 != 0; + let has_redirect = flags & 0x08 != 0; + let has_suggestions_type = flags & 0x10 != 0; + println!("flags: {}, node_type: {}, is_executable: {}, has_redirect: {}, has_suggestions_type: {}", flags, node_type, is_executable, has_redirect, has_suggestions_type); + + let children = buf.read_int_id_list().await?; + println!("children: {:?}", children); + let redirect_node = if has_redirect { + buf.read_varint().await? + } else { + 0 + }; + println!("redirect_node: {}", redirect_node); + + if node_type == 2 { + let name = buf.read_utf().await?; + println!("name: {}", name); + + let resource_location = if has_suggestions_type { + Some(buf.read_resource_location().await?) + } else { + None + }; + println!( + "node_type=2, flags={}, name={}, resource_location={:?}", + flags, name, resource_location + ); + return Ok(BrigadierNodeStub {}); + } + if node_type == 1 { + let name = buf.read_utf().await?; + println!("node_type=1, flags={}, name={}", flags, name); + return Ok(BrigadierNodeStub {}); + } + println!("node_type={}, flags={}", node_type, flags); + Ok(BrigadierNodeStub {}) + // return Err("Unknown node type".to_string()); + } +} diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index a4304d9f..2dbf7f24 100644 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -1,5 +1,6 @@ pub mod clientbound_change_difficulty_packet; pub mod clientbound_custom_payload_packet; +pub mod clientbound_declare_commands_packet; pub mod clientbound_login_packet; pub mod clientbound_update_view_distance_packet; @@ -10,8 +11,9 @@ declare_state_packets!( Serverbound => {}, Clientbound => { 0x0e: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket, + 0x12: clientbound_declare_commands_packet::ClientboundDeclareCommandsPacket, 0x18: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket, 0x26: clientbound_login_packet::ClientboundLoginPacket, - 0x4a: clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket, + 0x4a: clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket } );