quakeball-rust/rust/src/game_manager.rs
2026-07-17 20:13:44 +03:00

140 lines
3.7 KiB
Rust

use std::net::SocketAddr;
use godot::{prelude::*, tools::get_autoload_by_name};
use serde::{Deserialize, Serialize};
pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
#[derive(GodotClass)]
#[class(base=Node, init)]
pub struct GameManager {
pub game: Option<Gd<Game>>,
base: Base<Node>,
}
#[godot_api]
impl GameManager {
#[signal]
pub fn on_players_updated();
#[signal]
pub fn on_new_player(id: u16);
#[signal]
pub fn on_player_disconnected(id: u16);
pub fn singleton() -> Gd<GameManager> {
get_autoload_by_name::<GameManager>(GAME_MANAGER_GLOBAL)
}
pub fn init_game(&mut self, is_host: bool) {
if let Some(mut game) = self.game.take() {
game.queue_free();
}
let mut game = Game::new_alloc();
game.bind_mut().is_host = is_host;
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);
}
}
#[derive(GodotClass)]
#[class(base=Node, init)]
pub struct Game {
is_host: bool,
player_counter: u16,
pub self_id: Option<u16>,
pub players: Vec<Player>,
base: Base<Node>,
}
#[godot_api]
impl Game {
#[signal]
pub fn on_players_updated();
#[signal]
pub fn on_new_player(id: u16);
#[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);
}
pub fn new_player(&mut self, addr: SocketAddr, name: String) -> u16 {
let id = self.player_counter;
self.player_counter += 1;
self.players.push(Player {
id,
connection_addr: addr,
name,
ping: 0,
});
self.signals().on_new_player().emit(id);
id
}
pub fn set_players(&mut self, players: Vec<Player>) {
self.players = players;
for player in self.players.clone() {
self.signals().on_new_player().emit(player.id);
}
}
pub fn find_player_by_addr(&self, addr: &SocketAddr) -> Option<&Player> {
self.players.iter().find(|p| p.connection_addr == *addr)
}
pub fn get_player(&self, player_id: u16) -> Option<&Player> {
self.players.iter().find(|p| p.id == player_id)
}
pub fn remove_player(&mut self, id: u16) {
self.players.retain(|p| p.id != id);
self.signals().on_player_disconnected().emit(id);
}
pub fn update_player_nick(&mut self, player_id: u16, nick: String) {
if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
player.name = nick;
}
self.run_deferred(|s| s.signals().on_players_updated().emit());
}
pub fn update_player_ping(&mut self, player_id: u16, ping: u128) {
if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
player.ping = ping;
}
self.run_deferred(|s| s.signals().on_players_updated().emit());
}
}
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct Player {
pub id: u16,
pub connection_addr: SocketAddr,
pub name: String,
pub ping: u128,
}