chunkedge_registry/
tags.rs

1use std::borrow::Cow;
2
3use bevy_app::prelude::*;
4use bevy_ecs::prelude::*;
5use chunkedge_protocol::encode::{PacketWriter, WritePacket};
6pub use chunkedge_protocol::packets::play::update_tags_s2c::RegistryMap;
7use chunkedge_protocol::packets::play::UpdateTagsS2c;
8use chunkedge_server_common::Server;
9
10use crate::RegistrySet;
11
12#[derive(Debug, Resource, Default)]
13pub struct TagsRegistry {
14    pub registries: RegistryMap,
15    cached_packet: Vec<u8>,
16}
17
18pub(super) fn build(app: &mut App) {
19    app.init_resource::<TagsRegistry>()
20        .add_systems(PreStartup, init_tags_registry)
21        .add_systems(PostUpdate, cache_tags_packet.in_set(RegistrySet));
22}
23
24impl TagsRegistry {
25    fn build_synchronize_tags(&self) -> UpdateTagsS2c<'_> {
26        UpdateTagsS2c {
27            groups: Cow::Borrowed(&self.registries),
28        }
29    }
30
31    /// Returns bytes of the cached [`UpdateTagsS2c`] packet.
32    pub fn sync_tags_packet(&self) -> &[u8] {
33        &self.cached_packet
34    }
35}
36
37impl TagsRegistry {
38    pub fn default_tags() -> chunkedge_protocol::packets::configuration::UpdateTagsS2c<'static> {
39        let registries =
40            serde_json::from_str::<RegistryMap>(include_str!("../extracted/tags.json"))
41                .expect("tags.json must have expected structure");
42
43        chunkedge_protocol::packets::configuration::UpdateTagsS2c {
44            groups: Cow::Owned(registries),
45        }
46    }
47}
48
49fn init_tags_registry(mut tags: ResMut<TagsRegistry>) {
50    let registries = serde_json::from_str::<RegistryMap>(include_str!("../extracted/tags.json"))
51        .expect("tags.json must have expected structure");
52
53    tags.registries = registries;
54}
55
56pub(crate) fn cache_tags_packet(server: Res<Server>, tags: ResMut<TagsRegistry>) {
57    if tags.is_changed() {
58        let tags = tags.into_inner();
59        let packet = tags.build_synchronize_tags();
60        let mut bytes = vec![];
61        let mut writer = PacketWriter::new(&mut bytes, server.compression_threshold());
62
63        writer.write_packet(&packet);
64        tags.cached_packet = bytes;
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    /* TODO: move this to src/tests/
71    #[test]
72    fn smoke_test() {
73        let mut app = bevy_app::App::new();
74        app.add_plugins(RegistryPlugin);
75        // app.insert_resource(Server::default());
76        app.update();
77
78        let tags_registry = app.world.get_resource::<TagsRegistry>().unwrap();
79        let packet = tags_registry.build_synchronize_tags();
80        assert!(!packet.registries.is_empty());
81        assert!(!tags_registry.cached_packet.is_empty());
82    }
83    */
84}