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