1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

better parsing for entire login packet

This commit is contained in:
mat 2022-01-02 17:40:18 -06:00
parent 094c210dad
commit 45871fc01e
3 changed files with 151 additions and 91 deletions

View file

@ -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<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
buf.read_long().await
}
}
// u64
#[async_trait]
impl McBufReadable for u64 {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
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<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
buf.read_boolean().await
}
}
// GameType
#[async_trait]
impl McBufReadable for GameType {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
GameType::from_id(buf.read_byte().await?)
}
}
// Option<GameType>
#[async_trait]
impl McBufReadable for Option<GameType> {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
GameType::from_optional_id(buf.read_byte().await? as i8)
}
}
// Vec<ResourceLocation>
#[async_trait]
impl McBufReadable for Vec<ResourceLocation> {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
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<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
buf.read_nbt().await
}
}

View file

@ -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<u8>) -> 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<u8>) -> 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<u8>) -> 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<u8>) -> 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<u8>) -> Result<(), std::io::Error> {
buf.write_byte(*self)
}
}
// i64
impl McBufWritable for i64 {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
Writable::write_long(buf, *self)
}
}
// u64
impl McBufWritable for u64 {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
i64::write_into(&(*self as i64), buf)
}
}
// bool
impl McBufWritable for bool {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_boolean(*self)
}
}
// GameType
impl McBufWritable for GameType {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
u8::write_into(&self.to_id(), buf)
}
}
// Option<GameType>
impl McBufWritable for Option<GameType> {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_byte(GameType::to_optional_id(&self) as u8)
}
}
// Vec<ResourceLocation>
impl McBufWritable for Vec<ResourceLocation> {
fn write_into(&self, buf: &mut Vec<u8>) -> 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<u8>) -> Result<(), std::io::Error> {
buf.write_nbt(self)
}
}

View file

@ -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<u8>) -> 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<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
buf: &mut T,
) -> Result<GamePacket, String> {
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(&registry_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())
}
}