Skip to main content

chunkedge_server/
message.rs

1// TODO: delete this module in favor of chunkedge_chat.
2
3use bevy_app::prelude::*;
4use bevy_ecs::prelude::*;
5use chunkedge_protocol::IntoTextComponent;
6use chunkedge_protocol::encode::WritePacket;
7use chunkedge_protocol::packets::play::{ChatC2s, SystemChatS2c};
8use chunkedge_protocol::text::IntoText;
9
10use crate::event_loop::{EventLoopPreUpdate, PacketMessage};
11
12pub struct MessagePlugin;
13
14impl Plugin for MessagePlugin {
15    fn build(&self, app: &mut App) {
16        app.add_message::<ChatReceivedMessage>()
17            .add_systems(EventLoopPreUpdate, handle_chat_message);
18    }
19}
20
21pub trait SendMessage {
22    /// Sends a system message visible in the chat.
23    fn send_chat_message<'a>(&mut self, msg: impl IntoText<'a>);
24    /// Displays a message in the player's action bar (text above the hotbar).
25    fn send_action_bar_message<'a>(&mut self, msg: impl IntoText<'a>);
26}
27
28impl<T: WritePacket> SendMessage for T {
29    fn send_chat_message<'a>(&mut self, msg: impl IntoText<'a>) {
30        self.write_packet(&SystemChatS2c {
31            chat: msg.into_cow_text_component(),
32            overlay: false,
33        });
34    }
35
36    fn send_action_bar_message<'a>(&mut self, msg: impl IntoText<'a>) {
37        self.write_packet(&SystemChatS2c {
38            chat: msg.into_cow_text_component(),
39            overlay: true,
40        });
41    }
42}
43
44/// Message emitted when a client sends a chat message to the server.
45#[derive(Message, Clone, Debug)]
46pub struct ChatReceivedMessage {
47    /// The client that sent the chat message.
48    pub client: Entity,
49    /// The raw chat message text sent.
50    pub message: Box<str>,
51    /// The client-provided timestamp.
52    pub timestamp: u64,
53}
54
55pub fn handle_chat_message(
56    mut packets: MessageReader<PacketMessage>,
57    mut messages: MessageWriter<ChatReceivedMessage>,
58) {
59    for packet in packets.read() {
60        if let Some(pkt) = packet.decode::<ChatC2s>() {
61            messages.write(ChatReceivedMessage {
62                client: packet.client,
63                message: pkt.message.0.into(),
64                timestamp: pkt.timestamp,
65            });
66        }
67    }
68}