1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
use azalea_buf::AzBuf;
use azalea_core::{checksum::Checksum, registry_holder::RegistryHolder};
use azalea_inventory::{ItemStack, operations::ClickType};
use azalea_protocol_macros::ServerboundGamePacket;
use azalea_registry::builtin::{DataComponentKind, ItemKind};
use indexmap::IndexMap;
#[derive(AzBuf, Clone, Debug, PartialEq, ServerboundGamePacket)]
pub struct ServerboundContainerClick {
#[var]
pub container_id: i32,
#[var]
pub state_id: u32,
pub slot_num: i16,
pub button_num: u8,
pub click_type: ClickType,
pub changed_slots: IndexMap<u16, HashedStack>,
pub carried_item: HashedStack,
}
/// Similar to an [`ItemStack`] but only carrying a CRC32 hash of the value of
/// added data components instead of their entire contents.
#[derive(AzBuf, Clone, Debug, PartialEq)]
pub struct HashedStack(pub Option<HashedActualItem>);
#[derive(AzBuf, Clone, Debug, PartialEq)]
pub struct HashedActualItem {
pub kind: ItemKind,
#[var]
pub count: i32,
pub components: HashedPatchMap,
}
#[derive(AzBuf, Clone, Debug, PartialEq)]
pub struct HashedPatchMap {
#[limit(256)]
pub added_components: Vec<(DataComponentKind, Checksum)>,
#[limit(256)]
pub removed_components: Vec<DataComponentKind>,
}
impl HashedStack {
/// Convert your [`ItemStack`] into a [`HashedStack`] by hashing the data
/// components.
///
/// Minecraft uses this whenever the client sends data components to the
/// server.
///
/// The [`RegistryHolder`] is required as some components will hash
/// differently based on the server's registries.
pub fn from_item_stack(item: &ItemStack, registries: &RegistryHolder) -> Self {
let ItemStack::Present(item) = item else {
return HashedStack(None);
};
let mut added_components = Vec::new();
let mut removed_components = Vec::new();
for (kind, data) in item.component_patch.iter() {
if let Some(data) = data {
added_components.push((kind, data.crc_hash(registries)));
} else {
removed_components.push(kind);
}
}
let components = HashedPatchMap {
added_components,
removed_components,
};
let item = HashedActualItem {
kind: item.kind,
count: item.count,
components,
};
Self(Some(item))
}
}
|