From 45871fc01e212a50ac5e6268e4677f97f8fe5bb3 Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 2 Jan 2022 17:40:18 -0600 Subject: better parsing for entire login packet --- azalea-protocol/src/mc_buf/read.rs | 84 +++++++++++++++++++- azalea-protocol/src/mc_buf/write.rs | 68 ++++++++++++++-- .../src/packets/game/clientbound_login_packet.rs | 90 ++-------------------- 3 files changed, 151 insertions(+), 91 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 374e5443..5127860e 100644 --- a/azalea-protocol/src/mc_buf/read.rs +++ b/azalea-protocol/src/mc_buf/read.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use azalea_core::resource_location::ResourceLocation; +use azalea_core::{game_type::GameType, resource_location::ResourceLocation}; use tokio::io::{AsyncRead, AsyncReadExt}; use super::MAX_STRING_LENGTH; @@ -304,3 +304,85 @@ impl McBufVarintReadable for u16 { buf.read_varint().await.map(|i| i as u16) } } + +// i64 +#[async_trait] +impl McBufReadable for i64 { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + buf.read_long().await + } +} + +// u64 +#[async_trait] +impl McBufReadable for u64 { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + i64::read_into(buf).await.map(|i| i as u64) + } +} + +// bool +#[async_trait] +impl McBufReadable for bool { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + buf.read_boolean().await + } +} + +// GameType +#[async_trait] +impl McBufReadable for GameType { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + GameType::from_id(buf.read_byte().await?) + } +} + +// Option +#[async_trait] +impl McBufReadable for Option { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + GameType::from_optional_id(buf.read_byte().await? as i8) + } +} + +// Vec +#[async_trait] +impl McBufReadable for Vec { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + let mut vec = Vec::new(); + let length = buf.read_varint().await?; + for _ in 0..length { + vec.push(buf.read_resource_location().await?); + } + Ok(vec) + } +} + +// azalea_nbt::Tag +#[async_trait] +impl McBufReadable for azalea_nbt::Tag { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + buf.read_nbt().await + } +} diff --git a/azalea-protocol/src/mc_buf/write.rs b/azalea-protocol/src/mc_buf/write.rs index f22b218a..14dac9d1 100644 --- a/azalea-protocol/src/mc_buf/write.rs +++ b/azalea-protocol/src/mc_buf/write.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use azalea_core::resource_location::ResourceLocation; +use azalea_core::{game_type::GameType, resource_location::ResourceLocation}; use byteorder::{BigEndian, WriteBytesExt}; use std::io::Write; @@ -202,27 +202,85 @@ impl McBufWritable for ResourceLocation { // u32 impl McBufWritable for u32 { fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { - buf.write_varint(*self as i32) + i32::varint_write_into(&(*self as i32), buf) } } // u32 varint impl McBufVarintWritable for u32 { fn varint_write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { - buf.write_varint(*self as i32) + i32::varint_write_into(&(*self as i32), buf) } } // u16 impl McBufWritable for u16 { fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { - buf.write_varint(*self as i32) + i32::varint_write_into(&(*self as i32), buf) } } // u16 varint impl McBufVarintWritable for u16 { fn varint_write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { - buf.write_varint(*self as i32) + i32::varint_write_into(&(*self as i32), buf) + } +} + +// u8 +impl McBufWritable for u8 { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + buf.write_byte(*self) + } +} + +// i64 +impl McBufWritable for i64 { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + Writable::write_long(buf, *self) + } +} + +// u64 +impl McBufWritable for u64 { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + i64::write_into(&(*self as i64), buf) + } +} + +// bool +impl McBufWritable for bool { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + buf.write_boolean(*self) + } +} + +// GameType +impl McBufWritable for GameType { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + u8::write_into(&self.to_id(), buf) + } +} + +// Option +impl McBufWritable for Option { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + buf.write_byte(GameType::to_optional_id(&self) as u8) + } +} + +// Vec +impl McBufWritable for Vec { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + buf.write_list(&self, |buf, resource_location| { + buf.write_resource_location(resource_location) + }) + } +} + +// azalea_nbt::Tag +impl McBufWritable for azalea_nbt::Tag { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + buf.write_nbt(self) } } diff --git a/azalea-protocol/src/packets/game/clientbound_login_packet.rs b/azalea-protocol/src/packets/game/clientbound_login_packet.rs index 0286fce4..57869202 100644 --- a/azalea-protocol/src/packets/game/clientbound_login_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_login_packet.rs @@ -1,8 +1,7 @@ -use super::GamePacket; -use crate::mc_buf::{Readable, Writable}; use azalea_core::{game_type::GameType, resource_location::ResourceLocation}; +use packet_macros::GamePacket; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, GamePacket)] pub struct ClientboundLoginPacket { pub player_id: i32, pub hardcore: bool, @@ -13,93 +12,14 @@ pub struct ClientboundLoginPacket { pub dimension_type: azalea_nbt::Tag, pub dimension: ResourceLocation, pub seed: i64, + #[varint] pub max_players: i32, + #[varint] pub chunk_radius: i32, + #[varint] pub simulation_distance: i32, pub reduced_debug_info: bool, pub show_death_screen: bool, pub is_debug: bool, pub is_flat: bool, } - -impl ClientboundLoginPacket { - pub fn get(self) -> GamePacket { - GamePacket::ClientboundLoginPacket(self) - } - - pub fn write(&self, buf: &mut Vec) -> Result<(), std::io::Error> { - buf.write_int(self.player_id)?; - buf.write_boolean(self.hardcore)?; - buf.write_byte(self.game_type.to_id())?; - buf.write_byte(GameType::to_optional_id(&self.previous_game_type) as u8)?; - buf.write_list(&self.levels, |buf, resource_location| { - buf.write_resource_location(resource_location) - })?; - buf.write_nbt(&self.registry_holder)?; - buf.write_nbt(&self.dimension_type)?; - buf.write_resource_location(&self.dimension)?; - buf.write_long(self.seed)?; - buf.write_varint(self.max_players)?; - buf.write_varint(self.chunk_radius)?; - buf.write_varint(self.simulation_distance)?; - buf.write_boolean(self.reduced_debug_info)?; - buf.write_boolean(self.show_death_screen)?; - buf.write_boolean(self.is_debug)?; - buf.write_boolean(self.is_flat)?; - Ok(()) - } - - pub async fn read( - buf: &mut T, - ) -> Result { - let player_id = buf.read_int().await?; - let hardcore = buf.read_boolean().await?; - let game_type = GameType::from_id(buf.read_byte().await?)?; - let previous_game_type = GameType::from_optional_id(buf.read_byte().await? as i8)?; - - let mut levels = Vec::new(); - let length = buf.read_varint().await?; - for _ in 0..length { - levels.push(buf.read_resource_location().await?); - } - - // println!("about to read nbt"); - // // read all the bytes into a buffer, print it, and panic - // let mut registry_holder_buf = Vec::new(); - // buf.read_to_end(&mut registry_holder_buf).await.unwrap(); - // println!("{:?}", String::from_utf8_lossy(®istry_holder_buf)); - // panic!(""); - - let registry_holder = buf.read_nbt().await?; - let dimension_type = buf.read_nbt().await?; - let dimension = buf.read_resource_location().await?; - let seed = buf.read_long().await?; - let max_players = buf.read_varint().await?; - let chunk_radius = buf.read_varint().await?; - let simulation_distance = buf.read_varint().await?; - let reduced_debug_info = buf.read_boolean().await?; - let show_death_screen = buf.read_boolean().await?; - let is_debug = buf.read_boolean().await?; - let is_flat = buf.read_boolean().await?; - - Ok(ClientboundLoginPacket { - player_id, - hardcore, - game_type, - previous_game_type, - levels, - registry_holder, - dimension_type, - dimension, - seed, - max_players, - chunk_radius, - simulation_distance, - reduced_debug_info, - show_death_screen, - is_debug, - is_flat, - } - .get()) - } -} -- cgit v1.2.3