Skip to main content

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}