valence_server/
message.rs

1// TODO: delete this module in favor of valence_chat.
2
3use bevy_app::prelude::*;
4use bevy_ecs::prelude::*;
5use valence_protocol::encode::WritePacket;
6use valence_protocol::packets::play::{ChatMessageC2s, GameMessageS2c};
7use valence_protocol::text::IntoText;
8
9use crate::event_loop::{EventLoopPreUpdate, PacketEvent};
10
11pub struct MessagePlugin;
12
13impl Plugin for MessagePlugin {
14    fn build(&self, app: &mut App) {
15        app.add_event::<ChatMessageEvent>()
16            .add_systems(EventLoopPreUpdate, handle_chat_message);
17    }
18}
19
20pub trait SendMessage {
21    /// Sends a system message visible in the chat.
22    fn send_chat_message<'a>(&mut self, msg: impl IntoText<'a>);
23    /// Displays a message in the player's action bar (text above the hotbar).
24    fn send_action_bar_message<'a>(&mut self, msg: impl IntoText<'a>);
25}
26
27impl<T: WritePacket> SendMessage for T {
28    fn send_chat_message<'a>(&mut self, msg: impl IntoText<'a>) {
29        self.write_packet(&GameMessageS2c {
30            chat: msg.into_cow_text(),
31            overlay: false,
32        });
33    }
34
35    fn send_action_bar_message<'a>(&mut self, msg: impl IntoText<'a>) {
36        self.write_packet(&GameMessageS2c {
37            chat: msg.into_cow_text(),
38            overlay: true,
39        });
40    }
41}
42
43#[derive(Event, Clone, Debug)]
44pub struct ChatMessageEvent {
45    pub client: Entity,
46    pub message: Box<str>,
47    pub timestamp: u64,
48}
49
50pub fn handle_chat_message(
51    mut packets: EventReader<PacketEvent>,
52    mut events: EventWriter<ChatMessageEvent>,
53) {
54    for packet in packets.read() {
55        if let Some(pkt) = packet.decode::<ChatMessageC2s>() {
56            events.send(ChatMessageEvent {
57                client: packet.client,
58                message: pkt.message.0.into(),
59                timestamp: pkt.timestamp,
60            });
61        }
62    }
63}