Update player nick properly

This commit is contained in:
Sofia 2026-07-16 16:47:43 +03:00
parent 154c5fa743
commit 70c0a782b4
5 changed files with 136 additions and 36 deletions

View File

@ -3,8 +3,9 @@
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
font_size = 32
[node name="lobby" type="LobbyPanel" unique_id=915192272 node_paths=PackedStringArray("players_list")]
[node name="lobby" type="LobbyPanel" unique_id=915192272 node_paths=PackedStringArray("players_list", "name_field")]
players_list = NodePath("v_box_container/players_list")
name_field = NodePath("h_box_container/text_edit")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0

View File

@ -31,17 +31,22 @@ impl GameManager {
}
let mut game = Game::new_alloc();
game.bind_mut().is_host = is_host;
self.base_mut().add_child(&game);
game.signals()
.on_new_player()
.connect_other(self, |s, id| s.signals().on_new_player().emit(id));
game.signals()
.on_player_disconnected()
.connect_other(self, |s, id| s.signals().on_player_disconnected().emit(id));
game.signals()
.on_players_updated()
.connect_other(self, |s| s.signals().on_players_updated().emit());
self.run_deferred(|s| {
if let Some(game) = &s.game {
game.signals()
.on_new_player()
.connect_other(s, |s, id| s.signals().on_new_player().emit(id));
game.signals()
.on_player_disconnected()
.connect_other(s, |s, id| s.signals().on_player_disconnected().emit(id));
game.signals()
.on_players_updated()
.connect_other(s, |s| s.signals().on_players_updated().emit());
}
});
self.base_mut().add_child(&game);
self.game = Some(game);
}
@ -52,7 +57,7 @@ impl GameManager {
pub struct Game {
is_host: bool,
player_counter: u16,
self_id: Option<u16>,
pub self_id: Option<u16>,
pub players: Vec<Player>,
base: Base<Node>,
@ -67,6 +72,12 @@ impl Game {
#[signal]
pub fn on_player_disconnected(id: u16);
pub fn singleton() -> Option<Gd<Game>> {
GameManager::singleton()
.get_child(0)
.map(|g| g.cast::<Game>())
}
pub fn set_self(&mut self, id: u16) {
self.self_id = Some(id);
}
@ -93,7 +104,7 @@ impl Game {
}
pub fn remove_player(&mut self, id: u16) {
self.signals().on_new_player().emit(id);
self.signals().on_player_disconnected().emit(id);
self.players.retain(|p| p.id != id);
}
@ -101,7 +112,7 @@ impl Game {
if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
player.name = nick;
}
self.signals().on_players_updated().emit();
self.run_deferred(|s| s.signals().on_players_updated().emit());
}
}

View File

@ -5,7 +5,7 @@ use std::{
use godot::{prelude::*, tools::get_autoload_by_name};
use serde::{Deserialize, Serialize};
use teanet::{Peer, PeerConfig};
use teanet::{Peer, PeerConfig, PeerMessage};
use crate::{
game_manager::{Game, GameManager, Player},
@ -113,7 +113,7 @@ impl INode for NetworkManager {
self.peer = None;
GameManager::singleton().bind_mut().game = None;
}
teanet::PeerMessage::Message(msg) => match msg {
teanet::PeerMessage::Message(_, msg) => match msg {
Package::Hello => {
cli.bind_mut().publish_message(
format!("Got \"Hello\"!"),
@ -121,20 +121,23 @@ impl INode for NetworkManager {
);
}
Package::Players(players, self_id) => {
if let Some(game) =
&mut GameManager::singleton().bind_mut().game
{
cli.bind_mut().publish_message(
format!("Got players"),
CliColor::Info,
);
if let Some(game) = &mut Game::singleton() {
game.bind_mut().set_players(players);
game.bind_mut().set_self(self_id);
}
}
Package::SetNick(id, nick) => {
if let Some(game) =
&mut GameManager::singleton().bind_mut().game
{
game.bind_mut().update_player_nick(id, nick);
if let Some(game) = &mut Game::singleton() {
if game.bind().self_id != Some(id) {
game.bind_mut().update_player_nick(id, nick);
}
}
}
_ => {}
},
}
}
@ -153,9 +156,8 @@ impl INode for NetworkManager {
format!("Client connected from: {}", connection.address),
CliColor::Info,
);
if let Some(game) =
&mut GameManager::singleton().bind_mut().game
{
if let Some(game) = &mut Game::singleton() {
let self_id = game
.bind_mut()
.new_player(connection.address, String::new());
@ -176,9 +178,7 @@ impl INode for NetworkManager {
CliColor::Error,
);
}
if let Some(game) =
&mut GameManager::singleton().bind_mut().game
{
if let Some(game) = &mut Game::singleton() {
let player_id = game
.bind()
.find_player_by_addr(&connection.address)
@ -194,7 +194,22 @@ impl INode for NetworkManager {
self.peer = None;
GameManager::singleton().bind_mut().game = None;
}
teanet::PeerMessage::Message(msg) => match msg {
teanet::PeerMessage::Message(conn, msg) => match msg {
Package::SetSelfNick(nick) => {
if let Some(game) = &mut Game::singleton() {
let player = game
.bind()
.find_player_by_addr(&conn.address)
.cloned();
if let Some(player) = player {
peer.broadcast_reliable(Package::SetNick(
player.id,
nick.clone(),
));
game.bind_mut().update_player_nick(player.id, nick);
}
}
}
_ => {}
},
}
@ -230,7 +245,7 @@ impl NetworkManager {
self.swap_to_lobby(true);
if let Some(game) = &mut GameManager::singleton().bind_mut().game {
if let Some(game) = &mut Game::singleton() {
let id = game
.bind_mut()
.new_player(SocketAddr::from(([0, 0, 0, 0], 0)), "Host".to_owned());
@ -273,12 +288,23 @@ impl NetworkManager {
}
}
pub fn swap_to_lobby(&self, is_host: bool) {
fn swap_to_lobby(&self, is_host: bool) {
if let Some(scene) = &self.lobby_scene {
self.base().get_tree().change_scene_to_packed(scene);
GameManager::singleton().bind_mut().init_game(is_host);
}
}
pub fn update_nick(&mut self, nick: String) {
if let Some(peer) = &mut self.peer {
match peer {
PeerKind::Client(peer, addr) => {
peer.send_reliable(&addr, Package::SetSelfNick(nick));
}
PeerKind::Server(..) => {}
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -286,6 +312,7 @@ pub enum Package {
Hello,
Players(Vec<Player>, u16),
SetNick(u16, String),
SetSelfNick(String),
}
pub enum PeerKind {

View File

@ -1,19 +1,80 @@
use godot::{
classes::{IPanel, Panel, VBoxContainer},
classes::{IPanel, Label, Panel, TextEdit, VBoxContainer},
prelude::*,
};
use crate::{
game_manager::{Game, GameManager},
net::network_manager::NetworkManager,
};
#[derive(GodotClass)]
#[class(base=Panel, init)]
pub struct LobbyPanel {
#[export]
players_list: Option<Gd<VBoxContainer>>,
#[export]
name_field: Option<Gd<TextEdit>>,
base: Base<Panel>,
}
#[godot_api]
impl IPanel for LobbyPanel {
fn ready(&mut self) {}
fn process(&mut self, delta: f64) {}
fn ready(&mut self) {
GameManager::singleton()
.signals()
.on_new_player()
.connect_other(self, |s, _| s.update_players_list());
GameManager::singleton()
.signals()
.on_player_disconnected()
.connect_other(self, |s, _| s.update_players_list());
GameManager::singleton()
.signals()
.on_players_updated()
.connect_other(self, |s| s.update_players_list());
if let Some(name_field) = &self.name_field {
name_field
.signals()
.text_changed()
.connect_other(self, |s| {
if let Some(name_field) = &s.name_field {
if let Some(game) = &mut Game::singleton() {
let player_id = game.bind().self_id;
if let Some(player_id) = player_id {
game.bind_mut().update_player_nick(
player_id,
name_field.get_text().to_string(),
);
}
}
NetworkManager::singleton()
.bind_mut()
.update_nick(name_field.get_text().to_string());
}
});
}
self.update_players_list();
}
}
impl LobbyPanel {
pub fn update_players_list(&mut self) {
if let Some(list) = &mut self.players_list {
for child in list.get_children().iter_shared() {
list.remove_child(&child);
}
if let Some(game) = &GameManager::singleton().bind().game {
for player in &game.bind().players {
let mut label = Label::new_alloc();
label.set_text(&format!("{} ({})", player.name, player.connection_addr));
list.add_child(&label);
}
}
}
}
}

@ -1 +1 @@
Subproject commit a348dde42e9973488f89d1d89e4f0f24138654a6
Subproject commit 2721021f7b20831388d9ea7b3ea0797e3efdfdac