azalea_protocol/packets/game/
s_container_click.rs1use std::collections::HashMap;
2
3use azalea_buf::{AzBuf, AzaleaWrite};
4use azalea_inventory::{ItemStack, operations::ClickType};
5use azalea_protocol_macros::ServerboundGamePacket;
6
7#[derive(Clone, Debug, AzBuf, ServerboundGamePacket)]
8pub struct ServerboundContainerClick {
9 #[var]
10 pub container_id: i32,
11 #[var]
12 pub state_id: u32,
13 pub slot_num: i16,
14 pub button_num: u8,
15 pub click_type: ClickType,
16 pub changed_slots: HashMap<u16, HashedStack>,
17 pub carried_item: HashedStack,
18}
19
20#[derive(Clone, Debug, AzBuf)]
23pub struct HashedStack(pub Option<HashedActualItem>);
24
25#[derive(Clone, Debug, AzBuf)]
26pub struct HashedActualItem {
27 pub kind: azalea_registry::Item,
28 #[var]
29 pub count: i32,
30 pub components: HashedPatchMap,
31}
32
33#[derive(Clone, Debug, AzBuf)]
34pub struct HashedPatchMap {
35 #[limit(256)]
38 pub added_components: Vec<(azalea_registry::DataComponentKind, u32)>,
39 #[limit(256)]
40 pub removed_components: Vec<azalea_registry::DataComponentKind>,
41}
42
43#[cfg(feature = "crc32")]
50impl From<&ItemStack> for HashedStack {
51 fn from(item: &ItemStack) -> Self {
52 let ItemStack::Present(item) = item else {
53 return Self(None);
54 };
55
56 let mut added_components = Vec::new();
57 let mut removed_components = Vec::new();
58
59 for (&kind, data) in &item.components.components {
60 if let Some(data) = data {
61 let mut buf = Vec::new();
63 kind.azalea_write(&mut buf).unwrap();
64 data.encode(&mut buf).unwrap();
65 added_components.push((kind, crc32fast::hash(&buf)));
66 } else {
67 removed_components.push(kind);
68 }
69 }
70
71 let components = HashedPatchMap {
72 added_components,
73 removed_components,
74 };
75 let item = HashedActualItem {
76 kind: item.kind,
77 count: item.count,
78 components,
79 };
80 Self(Some(item))
81 }
82}