valence_protocol/packets/play/
synchronize_recipes_s2c.rs

1use std::borrow::Cow;
2use std::io::Write;
3
4use anyhow::ensure;
5use valence_ident::Ident;
6
7use crate::{Decode, Encode, ItemStack, Packet, RawBytes};
8
9#[derive(Clone, Debug, Encode, Decode, Packet)]
10pub struct SynchronizeRecipesS2c<'a> {
11    // TODO: this should be a Vec<Recipe<'a>>
12    pub recipes: RawBytes<'a>,
13}
14
15#[derive(Clone, Debug, Encode)]
16pub struct Recipe<'a> {
17    pub kind: Ident<Cow<'a, str>>,
18    pub recipe_id: Ident<Cow<'a, str>>,
19    pub data: RecipeData<'a>,
20}
21
22#[derive(Clone, Debug, Encode)]
23pub enum RecipeData<'a> {
24    CraftingShapeless(CraftingShapedData<'a>),
25    // TODO: fill in the rest.
26    CraftingShaped,
27    CraftingSpecialArmordye,
28    CraftingSpecialBookcloning,
29    CraftingSpecialMapcloning,
30    CraftingSpecialMapextending,
31    CraftingSpecialFireworkRocket,
32    CraftingSpecialFireworkStar,
33    CraftingSpecialFireworkStarFade,
34    CraftingSpecialRepairitem,
35    CraftingSpecialTippedarrow,
36    CraftingSpecialBannerduplicate,
37    CraftingSpecialShielddecoration,
38    CraftingSpecialShulkerboxcoloring,
39    CraftingSpecialSuspiciousStew,
40    CraftingDecoratedPot,
41    Smelting,
42    Blasting,
43    Smoking,
44    CampfireCooking,
45    Stonecutting,
46    SmithingTransform,
47    SmithingTrim,
48}
49
50#[derive(Clone, Debug)]
51pub struct CraftingShapedData<'a> {
52    pub width: u32,
53    pub height: u32,
54    pub group: &'a str,
55    pub category: CraftingShapedCategory,
56    /// Length must be width * height.
57    pub ingredients: Cow<'a, [Ingredient<'a>]>,
58    pub result: ItemStack,
59    pub show_notification: bool,
60}
61
62impl Encode for CraftingShapedData<'_> {
63    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
64        let Self {
65            width,
66            height,
67            group,
68            category,
69            ingredients,
70            result,
71            show_notification,
72        } = self;
73
74        width.encode(&mut w)?;
75        height.encode(&mut w)?;
76        group.encode(&mut w)?;
77        category.encode(&mut w)?;
78
79        let len = width
80            .checked_mul(*height)
81            .expect("bad shaped recipe dimensions") as usize;
82
83        ensure!(
84            len == ingredients.len(),
85            "number of ingredients in shaped recipe must be equal to width * height"
86        );
87
88        for ingr in ingredients.as_ref() {
89            ingr.encode(&mut w)?;
90        }
91
92        result.encode(&mut w)?;
93
94        show_notification.encode(w)
95    }
96}
97
98#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
99pub enum CraftingShapedCategory {
100    Building,
101    Redstone,
102    Equipment,
103    Misc,
104}
105
106pub type Ingredient<'a> = Cow<'a, [ItemStack]>;