azalea_client/plugins/
cookies.rs1use std::collections::HashMap;
5
6use azalea_protocol::packets::{
7 config,
8 game::{self},
9 login,
10};
11use azalea_registry::identifier::Identifier;
12use bevy_app::{App, Plugin};
13use bevy_ecs::{
14 component::Component,
15 entity::Entity,
16 event::EntityEvent,
17 observer::On,
18 system::{Commands, Query},
19};
20use tracing::warn;
21
22use crate::{
23 InConfigState, InGameState,
24 packet::{
25 config::SendConfigPacketEvent,
26 game::SendGamePacketEvent,
27 login::{InLoginState, SendLoginPacketEvent},
28 },
29};
30
31pub struct CookiesPlugin;
32impl Plugin for CookiesPlugin {
33 fn build(&self, app: &mut App) {
34 app.add_observer(handle_request_cookie)
35 .add_observer(handle_store_cookie);
36 }
37}
38
39#[derive(Component, Default)]
42pub struct ServerCookies {
43 pub map: HashMap<Identifier, Vec<u8>>,
44}
45
46#[derive(EntityEvent)]
47pub struct RequestCookieEvent {
48 pub entity: Entity,
49 pub key: Identifier,
50}
51#[derive(EntityEvent)]
52pub struct StoreCookieEvent {
53 pub entity: Entity,
54 pub key: Identifier,
55 pub payload: Vec<u8>,
56}
57
58#[allow(clippy::type_complexity)]
59pub fn handle_request_cookie(
60 request_cookie: On<RequestCookieEvent>,
61 mut commands: Commands,
62 query: Query<(
63 Option<&ServerCookies>,
64 Option<&InGameState>,
65 Option<&InConfigState>,
66 Option<&InLoginState>,
67 )>,
68) {
69 let Ok((server_cookies, in_game_state, in_config_state, in_login_state)) =
70 query.get(request_cookie.entity)
71 else {
72 return;
73 };
74
75 let key = request_cookie.key.clone();
76 let payload = server_cookies.and_then(|c| c.map.get(&key)).cloned();
77
78 if in_game_state.is_some() {
79 commands.trigger(SendGamePacketEvent::new(
80 request_cookie.entity,
81 game::ServerboundCookieResponse { key, payload },
82 ));
83 } else if in_config_state.is_some() {
84 commands.trigger(SendConfigPacketEvent::new(
85 request_cookie.entity,
86 config::ServerboundCookieResponse { key, payload },
87 ));
88 } else if in_login_state.is_some() {
89 commands.trigger(SendLoginPacketEvent::new(
90 request_cookie.entity,
91 login::ServerboundCookieResponse { key, payload },
92 ));
93 } else {
94 warn!("got RequestCookieEvent while in an unknown state")
95 }
96}
97pub fn handle_store_cookie(
98 store_cookie: On<StoreCookieEvent>,
99 mut query: Query<&mut ServerCookies>,
100) {
101 if let Ok(mut server_cookies) = query.get_mut(store_cookie.entity) {
102 server_cookies
103 .map
104 .insert(store_cookie.key.clone(), store_cookie.payload.clone());
105 } else {
106 warn!("got StoreCookieEvent for a client without ServerCookies")
107 }
108}