From f9528a9f9a9e73b1d657af7c78d743067307d843 Mon Sep 17 00:00:00 2001 From: mat Date: Tue, 26 Apr 2022 15:13:47 +0000 Subject: work on adding more stuff for recipes --- azalea-protocol/src/mc_buf/read.rs | 24 +++- .../game/clientbound_update_recipes_packet.rs | 130 ++++++++++++++++++++- 2 files changed, 146 insertions(+), 8 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 3d50e5aa..1e7db1dd 100755 --- a/azalea-protocol/src/mc_buf/read.rs +++ b/azalea-protocol/src/mc_buf/read.rs @@ -1,11 +1,12 @@ +use crate::mc_buf::ByteArray; use async_trait::async_trait; use azalea_chat::component::Component; use azalea_core::{ - difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation, + difficulty::Difficulty, game_type::GameType, resource_location::ResourceLocation, Slot, + SlotData, }; use serde::Deserialize; use tokio::io::{AsyncRead, AsyncReadExt}; -use crate::mc_buf::ByteArray; use super::MAX_STRING_LENGTH; @@ -252,7 +253,6 @@ impl McBufReadable for Vec { } } - #[async_trait] impl McBufReadable for ByteArray { async fn read_into(buf: &mut R) -> Result @@ -469,3 +469,21 @@ impl McBufReadable for Component { Ok(component) } } + +// Slot +#[async_trait] +impl McBufReadable for Slot { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + let present = buf.read_boolean().await?; + if !present { + return Ok(Slot::Empty); + } + let id = buf.read_varint().await?; + let count = buf.read_byte().await?; + let nbt = buf.read_nbt().await?; + Ok(Slot::Present(SlotData { id, count, nbt })) + } +} diff --git a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs index 8f9deae8..558b74c7 100644 --- a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs +++ b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs @@ -1,14 +1,134 @@ +use async_trait::async_trait; use azalea_chat::component::Component; -use azalea_core::resource_location::ResourceLocation; +use azalea_core::{resource_location::ResourceLocation, Slot}; use packet_macros::GamePacket; +use tokio::io::AsyncRead; + +use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable}; #[derive(Clone, Debug, GamePacket)] pub struct ClientboundUpdateRecipesPacket { pub recipes: Vec, } -struct Recipe { - type_: ResourceLocation, - identifier: ResourceLocation, - // data +#[derive(Clone, Debug)] +pub struct Recipe { + pub identifier: ResourceLocation, + pub data: RecipeData, +} + +#[derive(Clone, Debug)] +pub enum RecipeData { + CraftingShapeless { + /// Used to group similar recipes together in the recipe book. + /// Tag is present in recipe JSON + group: String, + // ingredients + ingredients: Vec, + result: Slot, + }, +} + +#[derive(Clone, Debug)] +pub struct Ingredient { + pub allowed: Vec, +} + +impl McBufWritable for Recipe { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + todo!() + } +} +#[async_trait] +impl McBufReadable for Recipe { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + let recipe_type = buf.read_resource_location().await?; + let identifier = buf.read_resource_location().await?; + + // rust doesn't let us match ResourceLocation so we have to do a big + // if-else chain :( + let data = if recipe_type == ResourceLocation::new("minecraft:crafting_shapeless").unwrap() + { + let group = buf.read_utf().await?; + let ingredients = Vec::::read_into(buf).await?; + let result = Slot::read_into(buf).await?; + + RecipeData::CraftingShapeless { + group, + ingredients, + result, + } + } else { + panic!(); + }; + + let recipe = Recipe { identifier, data }; + + Ok(recipe) + } +} + +impl McBufWritable for Ingredient { + fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { + todo!() + } +} +#[async_trait] +impl McBufReadable for Ingredient { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + let ingredient = Ingredient { + allowed: Vec::::read_into(buf).await?, + }; + Ok(ingredient) + } +} + +impl McBufWritable for Vec { + fn write_into(&self, buf: &mut Vec) -> 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 { + async fn read_into(buf: &mut R) -> Result + 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 { + fn write_into(&self, buf: &mut Vec) -> 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 { + async fn read_into(buf: &mut R) -> Result + where + R: AsyncRead + std::marker::Unpin + std::marker::Send, + { + todo!() + } } -- cgit v1.2.3