aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-04-26 15:13:47 +0000
committermat <github@matdoes.dev>2022-04-26 15:13:47 +0000
commitf9528a9f9a9e73b1d657af7c78d743067307d843 (patch)
treed24e46982572d3b8607e130a5f24a7f7c198f484
parent15b4dd6bd1c50ee8a9ebadf781e3ecbfdf62e266 (diff)
downloadazalea-drasl-f9528a9f9a9e73b1d657af7c78d743067307d843.tar.xz
work on adding more stuff for recipes
-rwxr-xr-xCargo.lock1
-rwxr-xr-xazalea-core/Cargo.toml1
-rwxr-xr-xazalea-core/src/lib.rs3
-rw-r--r--azalea-core/src/slot.rs16
-rwxr-xr-xazalea-protocol/src/mc_buf/read.rs24
-rw-r--r--azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs130
6 files changed, 167 insertions, 8 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8be7aa31..144a840b 100755
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -111,6 +111,7 @@ name = "azalea-core"
version = "0.1.0"
dependencies = [
"azalea-chat",
+ "azalea-nbt",
"uuid",
]
diff --git a/azalea-core/Cargo.toml b/azalea-core/Cargo.toml
index b0139999..d652a46e 100755
--- a/azalea-core/Cargo.toml
+++ b/azalea-core/Cargo.toml
@@ -7,4 +7,5 @@ version = "0.1.0"
[dependencies]
azalea-chat = {path = "../azalea-chat"}
+azalea-nbt = {path = "../azalea-nbt"}
uuid = "^0.8.2"
diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs
index cdf07c43..6f52e7e9 100755
--- a/azalea-core/src/lib.rs
+++ b/azalea-core/src/lib.rs
@@ -4,3 +4,6 @@ pub mod difficulty;
pub mod game_type;
pub mod resource_location;
pub mod serializable_uuid;
+
+mod slot;
+pub use slot::{Slot, SlotData};
diff --git a/azalea-core/src/slot.rs b/azalea-core/src/slot.rs
new file mode 100644
index 00000000..2e581586
--- /dev/null
+++ b/azalea-core/src/slot.rs
@@ -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,
+}
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<u8> {
}
}
-
#[async_trait]
impl McBufReadable for ByteArray {
async fn read_into<R>(buf: &mut R) -> Result<Self, String>
@@ -469,3 +469,21 @@ impl McBufReadable for 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 }))
+ }
+}
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<Recipe>,
}
-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<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!()
+ }
}