From 751098b636c9aee54b9ca7a465fdaa769f10be4d Mon Sep 17 00:00:00 2001 From: mat Date: Mon, 18 Apr 2022 22:38:53 -0500 Subject: start working on declare commands packet --- azalea-protocol/src/mc_buf/read.rs | 1 - .../game/clientbound_declare_commands_packet.rs | 133 +++++++++++++++------ azalea-protocol/src/packets/game/mod.rs | 9 ++ 3 files changed, 105 insertions(+), 38 deletions(-) (limited to 'azalea-protocol/src') diff --git a/azalea-protocol/src/mc_buf/read.rs b/azalea-protocol/src/mc_buf/read.rs index 0fa1d099..20b69238 100644 --- a/azalea-protocol/src/mc_buf/read.rs +++ b/azalea-protocol/src/mc_buf/read.rs @@ -2,7 +2,6 @@ use async_trait::async_trait; use azalea_core::{ difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation, }; -use num_traits::FromPrimitive; use tokio::io::{AsyncRead, AsyncReadExt}; use super::MAX_STRING_LENGTH; 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 crate::mc_buf::Readable; - -// use super::LoginPacket; - -// #[derive(Hash, Clone, Debug)] -// pub struct ClientboundDeclareCommandsPacket { -// pub root: RootCommandNode, -// pub public_key: Vec, -// pub nonce: Vec, -// } - -// impl ClientboundHelloPacket { -// pub fn get(self) -> LoginPacket { -// LoginPacket::ClientboundHelloPacket(self) -// } - -// pub fn write(&self, _buf: &mut Vec) -> Result<(), std::io::Error> { -// panic!("ClientboundHelloPacket::write not implemented") -// } - -// 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?; - -// Ok(ClientboundHelloPacket { -// server_id, -// public_key, -// nonce, -// } -// .get()) -// } -// } +use std::hash::Hash; + +use async_trait::async_trait; +use tokio::io::AsyncRead; + +use crate::mc_buf::{McBufReadable, Readable}; + +use super::GamePacket; + +#[derive(Hash, Clone, Debug)] +pub struct ClientboundDeclareCommandsPacket { + pub entries: Vec, + pub root_index: i32, +} + +impl ClientboundDeclareCommandsPacket { + pub fn get(self) -> GamePacket { + GamePacket::ClientboundDeclareCommandsPacket(self) + } + + pub fn write(&self, _buf: &mut Vec) -> Result<(), std::io::Error> { + panic!("ClientboundDeclareCommandsPacket::write not implemented") + } + + 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 4efe72fb..1fd47132 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; @@ -22,6 +23,9 @@ where ClientboundChangeDifficultyPacket( clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket, ), + ClientboundDeclareCommandsPacket( + clientbound_declare_commands_packet::ClientboundDeclareCommandsPacket, + ), } #[async_trait] @@ -32,6 +36,7 @@ impl ProtocolPacket for GamePacket { GamePacket::ClientboundCustomPayloadPacket(_packet) => 0x18, GamePacket::ClientboundLoginPacket(_packet) => 0x26, GamePacket::ClientboundUpdateViewDistancePacket(_packet) => 0x4a, + GamePacket::ClientboundDeclareCommandsPacket(_packet) => 0x12, } } @@ -41,6 +46,7 @@ impl ProtocolPacket for GamePacket { GamePacket::ClientboundCustomPayloadPacket(packet) => packet.write(buf), GamePacket::ClientboundLoginPacket(packet) => packet.write(buf), GamePacket::ClientboundUpdateViewDistancePacket(packet) => packet.write(buf), + GamePacket::ClientboundDeclareCommandsPacket(packet) => packet.write(buf), } } @@ -63,6 +69,9 @@ impl ProtocolPacket for GamePacket { 0x4a => clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket ::read(buf) .await?, + 0x12 => clientbound_declare_commands_packet::ClientboundDeclareCommandsPacket + ::read(buf) + .await?, // _ => return Err(format!("Unknown ServerToClient game packet id: {}", id)), _ => panic!("Unknown ServerToClient game packet id: {}", id), }, -- cgit v1.2.3