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

default implementation for read and write Vec<T>

This commit is contained in:
mat 2022-04-26 15:33:41 +00:00
parent f9528a9f9a
commit e5fcfa1193
10 changed files with 37 additions and 124 deletions

View file

@ -114,6 +114,9 @@ pub async fn join_server(address: &ServerAddress) -> Result<(), String> {
GamePacket::ClientboundDisconnectPacket(p) => {
println!("Got login disconnect packet {:?}", p);
}
GamePacket::ClientboundUpdateRecipesPacket(p) => {
println!("Got update recipes packet {:?}", p);
}
},
Err(e) => {
panic!("Error: {:?}", e);

View file

@ -4,18 +4,18 @@ mod read;
mod write;
pub use read::{McBufReadable, McBufVarintReadable, Readable};
pub use write::{McBufVarintWritable, McBufWritable, Writable};
use std::ops::Deref;
pub use write::{McBufVarintWritable, McBufWritable, Writable};
// const DEFAULT_NBT_QUOTA: u32 = 2097152;
const MAX_STRING_LENGTH: u16 = 32767;
// const MAX_COMPONENT_STRING_LENGTH: u32 = 262144;
/// A Vec<u8> that isn't prefixed by a VarInt with the size.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ByteArray(Vec<u8>);
pub struct UnsizedByteArray(Vec<u8>);
impl Deref for ByteArray {
impl Deref for UnsizedByteArray {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
@ -23,13 +23,12 @@ impl Deref for ByteArray {
}
}
impl From<Vec<u8>> for ByteArray {
impl From<Vec<u8>> for UnsizedByteArray {
fn from(vec: Vec<u8>) -> Self {
Self(vec)
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1,4 +1,3 @@
use crate::mc_buf::ByteArray;
use async_trait::async_trait;
use azalea_chat::component::Component;
use azalea_core::{
@ -8,7 +7,7 @@ use azalea_core::{
use serde::Deserialize;
use tokio::io::{AsyncRead, AsyncReadExt};
use super::MAX_STRING_LENGTH;
use super::{UnsizedByteArray, MAX_STRING_LENGTH};
#[async_trait]
pub trait Readable {
@ -16,7 +15,7 @@ pub trait Readable {
async fn read_varint(&mut self) -> Result<i32, String>;
fn get_varint_size(&mut self, value: i32) -> u8;
fn get_varlong_size(&mut self, value: i32) -> u8;
async fn read_byte_array(&mut self) -> Result<ByteArray, String>;
async fn read_byte_array(&mut self) -> Result<Vec<u8>, String>;
async fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, String>;
async fn read_bytes(&mut self) -> Result<Vec<u8>, String>;
async fn read_utf(&mut self) -> Result<String, String>;
@ -82,9 +81,9 @@ where
10
}
async fn read_byte_array(&mut self) -> Result<ByteArray, String> {
async fn read_byte_array(&mut self) -> Result<Vec<u8>, String> {
let length = self.read_varint().await? as usize;
Ok(ByteArray(self.read_bytes_with_len(length).await?))
self.read_bytes_with_len(length).await
}
async fn read_bytes_with_len(&mut self, n: usize) -> Result<Vec<u8>, String> {
@ -244,22 +243,27 @@ impl McBufVarintReadable for i32 {
}
#[async_trait]
impl McBufReadable for Vec<u8> {
impl McBufReadable for UnsizedByteArray {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
buf.read_bytes().await
Ok(UnsizedByteArray(buf.read_bytes().await?))
}
}
#[async_trait]
impl McBufReadable for ByteArray {
impl<T: McBufReadable + Send> McBufReadable for Vec<T> {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
buf.read_byte_array().await
let length = buf.read_varint().await? as usize;
let mut contents = Vec::with_capacity(length);
for _ in 0..length {
contents.push(T::read_into(buf).await?);
}
Ok(contents)
}
}
@ -417,22 +421,6 @@ impl McBufReadable for Option<GameType> {
}
}
// 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 {

View file

@ -1,5 +1,4 @@
use super::MAX_STRING_LENGTH;
use crate::mc_buf::ByteArray;
use super::{UnsizedByteArray, MAX_STRING_LENGTH};
use async_trait::async_trait;
use azalea_chat::component::Component;
use azalea_core::{
@ -187,15 +186,17 @@ impl McBufVarintWritable for i32 {
}
}
impl McBufWritable for Vec<u8> {
impl McBufWritable for UnsizedByteArray {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_bytes(self)
}
}
impl McBufWritable for ByteArray {
// TODO: use specialization when that gets stabilized into rust
// to optimize for Vec<u8> byte arrays
impl<T: McBufWritable> McBufWritable for Vec<T> {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_byte_array(&self)
buf.write_list(self, |buf, i| T::write_into(i, buf))
}
}
@ -304,15 +305,6 @@ impl McBufWritable for Option<GameType> {
}
}
// 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> {

View file

@ -1,8 +1,9 @@
use crate::mc_buf::UnsizedByteArray;
use azalea_core::resource_location::ResourceLocation;
use packet_macros::GamePacket;
#[derive(Clone, Debug, GamePacket)]
pub struct ClientboundCustomPayloadPacket {
pub identifier: ResourceLocation,
pub data: Vec<u8>,
pub data: UnsizedByteArray,
}

View file

@ -88,47 +88,3 @@ impl McBufReadable for Ingredient {
Ok(ingredient)
}
}
impl McBufWritable for Vec<Recipe> {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_varint(self.len() as i32)?;
for recipe in self {
recipe.write_into(buf)?;
}
Ok(())
}
}
#[async_trait]
impl McBufReadable for Vec<Recipe> {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
let recipe_count = buf.read_varint().await?;
let mut recipes = Vec::with_capacity(recipe_count as usize);
for _ in 0..recipe_count {
recipes.push(Recipe::read_into(buf).await?);
}
Ok(recipes)
}
}
impl McBufWritable for Vec<Ingredient> {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_varint(self.len() as i32)?;
for ingredient in self {
ingredient.write_into(buf)?;
}
Ok(())
}
}
#[async_trait]
impl McBufReadable for Vec<Ingredient> {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
todo!()
}
}

View file

@ -54,33 +54,6 @@ impl McBufWritable for HashMap<ResourceLocation, Vec<Tags>> {
Ok(())
}
}
#[async_trait]
impl McBufReadable for Vec<Tags> {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
let tags_count = buf.read_varint().await? as usize;
let mut tags_vec = Vec::with_capacity(tags_count);
for _ in 0..tags_count {
let tags = Tags::read_into(buf).await?;
tags_vec.push(tags);
}
Ok(tags_vec)
}
}
impl McBufWritable for Vec<Tags> {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_varint(self.len() as i32)?;
for tag in self {
tag.write_into(buf)?;
}
Ok(())
}
}
#[async_trait]
impl McBufReadable for Tags {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>

View file

@ -1,3 +1,4 @@
use crate::mc_buf::UnsizedByteArray;
use azalea_core::resource_location::ResourceLocation;
use packet_macros::LoginPacket;
use std::hash::Hash;
@ -7,5 +8,5 @@ pub struct ClientboundCustomQueryPacket {
#[varint]
pub transaction_id: u32,
pub identifier: ResourceLocation,
pub data: Vec<u8>,
pub data: UnsizedByteArray,
}

View file

@ -1,13 +1,13 @@
use std::hash::Hash;
use super::LoginPacket;
use crate::mc_buf::{ByteArray, Readable};
use crate::mc_buf::Readable;
#[derive(Hash, Clone, Debug)]
pub struct ClientboundHelloPacket {
pub server_id: String,
pub public_key: ByteArray,
pub nonce: ByteArray,
pub public_key: Vec<u8>,
pub nonce: Vec<u8>,
}
impl ClientboundHelloPacket {

View file

@ -1,10 +1,10 @@
use super::LoginPacket;
use crate::mc_buf::{ByteArray, Writable};
use crate::mc_buf::Writable;
use packet_macros::LoginPacket;
use std::hash::Hash;
#[derive(Hash, Clone, Debug, LoginPacket)]
pub struct ServerboundKeyPacket {
pub shared_secret: ByteArray,
pub nonce: ByteArray,
pub shared_secret: Vec<u8>,
pub nonce: Vec<u8>,
}