140 lines
3.7 KiB
Rust
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,
|
|
}
|