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

work on adding more stuff for recipes

This commit is contained in:
mat 2022-04-26 15:13:47 +00:00
parent 15b4dd6bd1
commit f9528a9f9a
6 changed files with 167 additions and 8 deletions

1
Cargo.lock generated
View file

@ -111,6 +111,7 @@ name = "azalea-core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"azalea-chat", "azalea-chat",
"azalea-nbt",
"uuid", "uuid",
] ]

View file

@ -7,4 +7,5 @@ version = "0.1.0"
[dependencies] [dependencies]
azalea-chat = {path = "../azalea-chat"} azalea-chat = {path = "../azalea-chat"}
azalea-nbt = {path = "../azalea-nbt"}
uuid = "^0.8.2" uuid = "^0.8.2"

View file

@ -4,3 +4,6 @@ pub mod difficulty;
pub mod game_type; pub mod game_type;
pub mod resource_location; pub mod resource_location;
pub mod serializable_uuid; pub mod serializable_uuid;
mod slot;
pub use slot::{Slot, SlotData};

16
azalea-core/src/slot.rs Normal file
View file

@ -0,0 +1,16 @@
// TODO: have an azalea-inventory crate and put this there
#[derive(Debug, Clone)]
pub enum Slot {
Present(SlotData),
Empty,
}
#[derive(Debug, Clone)]
pub struct SlotData {
pub id: i32,
// TODO: is this really a u8? is it a i8? is it a varint?
// wiki.vg says it's a "byte"
pub count: u8,
pub nbt: azalea_nbt::Tag,
}

View file

@ -1,11 +1,12 @@
use crate::mc_buf::ByteArray;
use async_trait::async_trait; use async_trait::async_trait;
use azalea_chat::component::Component; use azalea_chat::component::Component;
use azalea_core::{ 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 serde::Deserialize;
use tokio::io::{AsyncRead, AsyncReadExt}; use tokio::io::{AsyncRead, AsyncReadExt};
use crate::mc_buf::ByteArray;
use super::MAX_STRING_LENGTH; use super::MAX_STRING_LENGTH;
@ -252,7 +253,6 @@ impl McBufReadable for Vec<u8> {
} }
} }
#[async_trait] #[async_trait]
impl McBufReadable for ByteArray { impl McBufReadable for ByteArray {
async fn read_into<R>(buf: &mut R) -> Result<Self, String> async fn read_into<R>(buf: &mut R) -> Result<Self, String>
@ -469,3 +469,21 @@ impl McBufReadable for Component {
Ok(component) Ok(component)
} }
} }
// Slot
#[async_trait]
impl McBufReadable for Slot {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
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 }))
}
}

View file

@ -1,14 +1,134 @@
use async_trait::async_trait;
use azalea_chat::component::Component; use azalea_chat::component::Component;
use azalea_core::resource_location::ResourceLocation; use azalea_core::{resource_location::ResourceLocation, Slot};
use packet_macros::GamePacket; use packet_macros::GamePacket;
use tokio::io::AsyncRead;
use crate::mc_buf::{McBufReadable, McBufWritable, Readable, Writable};
#[derive(Clone, Debug, GamePacket)] #[derive(Clone, Debug, GamePacket)]
pub struct ClientboundUpdateRecipesPacket { pub struct ClientboundUpdateRecipesPacket {
pub recipes: Vec<Recipe>, pub recipes: Vec<Recipe>,
} }
struct Recipe { #[derive(Clone, Debug)]
type_: ResourceLocation, pub struct Recipe {
identifier: ResourceLocation, pub identifier: ResourceLocation,
// data 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<Ingredient>,
result: Slot,
},
}
#[derive(Clone, Debug)]
pub struct Ingredient {
pub allowed: Vec<Slot>,
}
impl McBufWritable for Recipe {
fn write_into(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
todo!()
}
}
#[async_trait]
impl McBufReadable for Recipe {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
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::<Ingredient>::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<u8>) -> Result<(), std::io::Error> {
todo!()
}
}
#[async_trait]
impl McBufReadable for Ingredient {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
where
R: AsyncRead + std::marker::Unpin + std::marker::Send,
{
let ingredient = Ingredient {
allowed: Vec::<Slot>::read_into(buf).await?,
};
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!()
}
} }