From beefa22d5944e14942d064be725c922df8ed46a0 Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 24 Jul 2026 04:11:18 +0300 Subject: [PATCH] Add sending chat messages as well --- godot/scenes/ui/chat_box.tscn | 1 - rust/src/chat.rs | 9 +++++++++ rust/src/game_manager.rs | 14 ++++++++++++++ rust/src/net/network_manager.rs | 1 + rust/src/net/protocol.rs | 14 ++++++++++++++ rust/src/ui/chatbox.rs | 34 ++++++++++++++++++++++++++++++--- 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/godot/scenes/ui/chat_box.tscn b/godot/scenes/ui/chat_box.tscn index 9566448..d74572a 100644 --- a/godot/scenes/ui/chat_box.tscn +++ b/godot/scenes/ui/chat_box.tscn @@ -6,7 +6,6 @@ bg_color = Color(0.6, 0.6, 0.6, 0) [node name="chat_box" type="ChatBox" unique_id=1125601400 node_paths=PackedStringArray("messages", "line_edit")] messages = NodePath("panel/scroll_container/v_box_container") line_edit = NodePath("line_edit") -show_edit = true custom_minimum_size = Vector2(500, 300) custom_maximum_size = Vector2(500, 300) offset_right = 500.0 diff --git a/rust/src/chat.rs b/rust/src/chat.rs index 9df325f..c0db896 100644 --- a/rust/src/chat.rs +++ b/rust/src/chat.rs @@ -37,6 +37,7 @@ impl Chat { pub enum ChatMessage { Death(DamageSource, u16), Announcement(u16, Announcement), + ChatMessage(u16, String), } impl ChatMessage { @@ -78,6 +79,14 @@ impl ChatMessage { label.append_text(&format!("[color=red]{}[/color]", what)); } } + ChatMessage::ChatMessage(player_id, message) => { + if let Some(game) = Game::singleton() + && let Some(player) = game.bind().find_player(*player_id) + { + add_player(&mut label, &player); + label.add_text(message); + } + } } label } diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index 84b4173..afb5152 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -907,6 +907,20 @@ impl Game { }); } + pub fn on_chat_message(&mut self, player_id: u16, message: String) { + if let Some(chat) = &mut Chat::singleton() { + chat.bind_mut() + .new_message(ChatMessage::ChatMessage(player_id, message.clone())); + } + self.run_deferred(move |_| { + if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer + && let PeerKind::Server(peer, _) = peer + { + peer.broadcast_reliable(Package::ChatMessage(player_id, message.clone())); + } + }); + } + pub fn on_announcement(&mut self, player_id: u16, announcement: Announcement) { if let Some(chat) = &mut Chat::singleton() { chat.bind_mut() diff --git a/rust/src/net/network_manager.rs b/rust/src/net/network_manager.rs index 090966e..e2cef2a 100644 --- a/rust/src/net/network_manager.rs +++ b/rust/src/net/network_manager.rs @@ -292,6 +292,7 @@ pub enum Package { PlayerLeft(NetPlayer), SetTeam(u16, u8), GameOptionChanged(GameOption, GameOptionValue), + ChatMessage(u16, String), // Lobby packages SetReady(u16, bool), diff --git a/rust/src/net/protocol.rs b/rust/src/net/protocol.rs index 9ebdde2..8127838 100644 --- a/rust/src/net/protocol.rs +++ b/rust/src/net/protocol.rs @@ -205,6 +205,11 @@ impl NetworkManager { game.bind_mut().on_announcement(source_id, announcement); } } + Package::ChatMessage(source_id, message) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().on_chat_message(source_id, message); + } + } _ => {} }, }, @@ -372,6 +377,15 @@ impl NetworkManager { } } } + Package::ChatMessage(_, message) => { + if let Some(game) = &mut Game::singleton() { + let player = + game.bind().find_player_by_addr(&conn.address).cloned(); + if let Some(player) = player { + game.bind_mut().on_chat_message(player.id(), message); + } + } + } _ => {} }, }, diff --git a/rust/src/ui/chatbox.rs b/rust/src/ui/chatbox.rs index bd0bfe7..d79c79a 100644 --- a/rust/src/ui/chatbox.rs +++ b/rust/src/ui/chatbox.rs @@ -1,15 +1,22 @@ use godot::{ classes::{ - Engine, IVBoxContainer, InputEvent, LineEdit, Panel, RichTextLabel, TextEdit, VBoxContainer, + Engine, IVBoxContainer, InputEvent, LineEdit, Panel, RichTextLabel, ScrollContainer, + TextEdit, VBoxContainer, }, prelude::*, }; -use crate::chat::Chat; +use crate::{ + chat::Chat, + game_manager::Game, + net::network_manager::{NetworkManager, Package, PeerKind}, +}; #[derive(GodotClass)] #[class(base=VBoxContainer, init, tool)] pub struct ChatBox { + #[export] + scroll: Option>, #[export] messages: Option>, #[export] @@ -81,10 +88,15 @@ impl ChatBox { if let Some(messages) = &mut self.messages { messages.add_child(&message); } + self.run_deferred(|s| { + if let Some(scroll) = &mut s.scroll { + scroll.set_h_scroll(i32::MAX); + scroll.set_v_scroll(i32::MAX); + } + }); } pub fn on_submit(&mut self, message: GString) { - godot_print!("{}", message); if let Some(line_edit) = &mut self.line_edit { line_edit.clear(); if self.in_game { @@ -92,6 +104,22 @@ impl ChatBox { } } self.signals().on_closed().emit(); + if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { + match peer { + PeerKind::Client(peer, socket_addr) => { + peer.send_reliable(socket_addr, Package::ChatMessage(0, message.to_string())); + } + PeerKind::Server(..) => { + self.run_deferred(move |_| { + if let Some(game) = &mut Game::singleton() { + let self_id = game.bind().self_id; + game.bind_mut() + .on_chat_message(self_id.unwrap_or(0), message.to_string()); + } + }); + } + } + } } pub fn is_editing(&self) -> bool {