ghast_client/interest.rs
1//! Which optional packet groups a behaviour wants.
2//!
3//! The client always receives what its core needs (keep-alive, teleports, health, windows'
4//! confirm transactions, chunk headers, …). Everything else is dropped by the frame
5//! decoder *before* it is decoded — when compression is on, after inflating only the bytes
6//! that hold the packet id. A busy server's tab list, teams, particles, sounds and entity
7//! movement therefore cost almost nothing unless a behaviour asks for them.
8
9use std::ops::{BitOr, BitOrAssign};
10
11/// A set of optional packet groups (see the associated constants).
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
13pub struct Interests(u32);
14
15impl Interests {
16 /// Nothing optional.
17 pub const NONE: Interests = Interests(0);
18 /// Chat messages ([`crate::TickEvents::chat`]).
19 pub const CHAT: Interests = Interests(1 << 0);
20 /// Entities (spawns, moves, metadata, equipment, effects): [`crate::TickContext::entities`]
21 /// and the entity crosshair / attack / interact. Can be switched at run time: tracking then
22 /// starts empty (entities already spawned stay unknown until the server sends them again)
23 /// and switching off frees the store.
24 pub const ENTITIES: Interests = Interests(1 << 1);
25 /// The tab list (player names and UUIDs) on top of [`Interests::ENTITIES`] — the most
26 /// expensive packet on busy servers. Switching it restarts the tracker empty.
27 pub const PLAYER_LIST: Interests = Interests(1 << 2);
28 /// Skin / cape textures (the base64 `"textures"` profile property) of tab-list entries,
29 /// on top of [`Interests::PLAYER_LIST`] (`PlayerInfo::textures`). Switching it restarts
30 /// the tracker empty.
31 pub const PLAYER_SKINS: Interests = Interests(1 << 4);
32 /// Block changes (1.8 S23/S22, 1.16 block_change / multi_block_change) as
33 /// [`crate::TickEvents::block_updates`]. The world applies them either way; this only
34 /// collects them for the behaviour.
35 pub const BLOCK_UPDATES: Interests = Interests(1 << 3);
36
37 /// Whether every group in `other` is in `self`.
38 #[must_use]
39 pub const fn contains(self, other: Interests) -> bool {
40 self.0 & other.0 == other.0
41 }
42
43 /// The union of two sets.
44 #[must_use]
45 pub const fn union(self, other: Interests) -> Interests {
46 Interests(self.0 | other.0)
47 }
48}
49
50impl BitOr for Interests {
51 type Output = Interests;
52 fn bitor(self, rhs: Interests) -> Interests {
53 self.union(rhs)
54 }
55}
56
57impl BitOrAssign for Interests {
58 fn bitor_assign(&mut self, rhs: Interests) {
59 *self = self.union(rhs);
60 }
61}