From d1282693da1da8843c8dc8346e932f6aabdd7d68 Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 21 Jul 2026 22:53:14 +0300 Subject: [PATCH] Move sync and net processing to physics_process --- rust/src/game_manager.rs | 2 +- rust/src/net/mod.rs | 1 + rust/src/net/network_manager.rs | 384 +++----------------------------- rust/src/net/protocol.rs | 310 ++++++++++++++++++++++++++ 4 files changed, 340 insertions(+), 357 deletions(-) create mode 100644 rust/src/net/protocol.rs diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index 65ebd4d..a1a1f00 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -106,7 +106,7 @@ pub struct Game { #[godot_api] impl INode for Game { - fn process(&mut self, delta: f64) { + fn physics_process(&mut self, delta: f64) { self.since_last_sync += delta; if self.since_last_sync > (1. / 60.) { self.since_last_sync = 0.; diff --git a/rust/src/net/mod.rs b/rust/src/net/mod.rs index 0ff753d..d6e4a7f 100644 --- a/rust/src/net/mod.rs +++ b/rust/src/net/mod.rs @@ -1,3 +1,4 @@ pub mod net_stats; pub mod network_manager; +pub mod protocol; pub mod util; diff --git a/rust/src/net/network_manager.rs b/rust/src/net/network_manager.rs index eb07919..477ca36 100644 --- a/rust/src/net/network_manager.rs +++ b/rust/src/net/network_manager.rs @@ -6,7 +6,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, NetPlayer}, @@ -66,10 +66,8 @@ impl INode for NetworkManager { .connect_other(self, |s| s.disconnect()); } - fn process(&mut self, _delta: f64) { + fn physics_process(&mut self, _delta: f64) { if let Some(peer) = &mut self.peer { - let mut cli = CommandLinePanel::singleton(); - let now = Instant::now(); if now - self.last_netstat_update > Duration::from_millis(1000) { Stats::singleton().bind_mut().update_stats(match peer { @@ -112,363 +110,37 @@ impl INode for NetworkManager { } } - match peer { - PeerKind::Client(peer, _) => match peer.poll() { - Ok(message) => { - if let Some(message) = message { - match message { - teanet::PeerMessage::NewConnection(connection) => { - cli.bind_mut().publish_message( - format!("Connected to: {}", connection.address), - CliColor::Info, - ); - self.swap_to_lobby(false); - } - teanet::PeerMessage::Disconnected(connection, connection_error) => { - cli.bind_mut().publish_message( - format!("Disconnected from: {}", connection.address), - CliColor::Info, - ); - if let Some(err) = &connection_error { - cli.bind_mut().publish_message( - format!("Error with connection: {}", err), - CliColor::Error, - ); - } - peer.close(); - } - teanet::PeerMessage::Closed => { - self.peer = None; - GameManager::singleton().bind_mut().game = None; - } - teanet::PeerMessage::Message(_, msg) => match msg { - Package::Hello => { - cli.bind_mut().publish_message( - format!("Got \"Hello\"!"), - CliColor::Info, - ); - } - Package::Players(players, self_id) => { - cli.bind_mut().publish_message( - format!("Got players"), - CliColor::Info, - ); - if let Some(game) = &mut Game::singleton() { - game.bind_mut().set_players( - players - .into_iter() - .map(|p| p.clone().into()) - .collect(), - ); - game.bind_mut().set_self(self_id); - } - } - Package::SetNick(id, nick) => { - if let Some(game) = &mut Game::singleton() { - if game.bind().self_id != Some(id) { - game.bind_mut().update_player_nick(id, nick); - } - } - } - Package::UpdatePings(pings) => { - if let Some(game) = &mut Game::singleton() { - for (player_id, ping) in pings { - game.bind_mut().update_player_ping(player_id, ping); - } - } - } - Package::NewPlayer(player) => { - if let Some(game) = &mut Game::singleton() { - if player.id != game.bind().self_id.unwrap_or(u16::MAX) - { - game.bind_mut().new_player( - SocketAddr::from(([0, 0, 0, 0], 0)), - player.name, - Some(player.id), - ); - } - } - } - Package::PlayerLeft(player) => { - if let Some(game) = &mut Game::singleton() { - if player.id != game.bind().self_id.unwrap_or(u16::MAX) - { - game.bind_mut().remove_player(player.id); - } - } - } - Package::SetReady(player_id, is_ready) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut() - .update_player_ready(player_id, is_ready); - } - } - Package::SelectMap(map_id) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().change_map_selection(map_id, true); - } - } - Package::GameStarted => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().start_game(); - } - } - Package::SpawnPlayer(id, transform) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().spawn_player_client(id, transform); - } - } - Package::Sync(sync_data, ball_sync) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().handle_sync(sync_data, ball_sync); - } - } - Package::Jump(player_id) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().handle_jump(player_id); - } - } - Package::Shoot(player_id, to, transform, look_up) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().handle_shoot( - player_id, - to.into(), - transform, - look_up, - false, - ); - } - } - Package::TakeDamage( - source_player_id, - target_player_id, - damage, - ) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().handle_take_damage( - source_player_id, - target_player_id, - damage, - ); - } - } - Package::Kill(source_player_id, target_player_id) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut() - .handle_kill(source_player_id, target_player_id); - } - } - Package::SpawnBall(transform, velocity, player_id) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().spawn_ball( - Some(transform), - Some(velocity), - player_id, - ); - } - } - Package::DespawnBall => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().despawn_ball(); - } - } - Package::SwapWeapon(id, weapon_type) => { - if let Some(game) = &mut Game::singleton() { - game.bind_mut().handle_swap_weapon( - id, - weapon_type, - true, - ); - } - } - _ => {} - }, - } - } - } - Err(err) => { - cli.bind_mut() - .publish_message(format!("Error: {}", err), CliColor::Info); - } - }, - PeerKind::Server(peer, _) => match peer.poll() { - Ok(message) => { - if let Some(message) = message { - match message { - teanet::PeerMessage::NewConnection(connection) => { - cli.bind_mut().publish_message( - format!("Client connected from: {}", connection.address), - CliColor::Info, - ); - - if let Some(game) = &mut Game::singleton() { - let self_id = game.bind_mut().new_player( - connection.address, - String::new(), - None, - ); - peer.send_reliable( - &connection.address, - Package::Players( - game.bind() - .players - .clone() - .into_iter() - .map(|p| p.into()) - .collect(), - self_id, - ), - ); - peer.broadcast_reliable(Package::NewPlayer( - game.bind() - .find_player(self_id) - .unwrap() - .clone() - .into(), - )); - - peer.send_reliable( - &connection.address, - Package::SelectMap(game.bind().selected_map_idx), - ); - } - } - teanet::PeerMessage::Disconnected(connection, connection_error) => { - cli.bind_mut().publish_message( - format!("Client disconnected: {}", connection.address), - CliColor::Info, - ); - if let Some(err) = &connection_error { - cli.bind_mut().publish_message( - format!("Error with connection: {}", err), - CliColor::Error, - ); - } - if let Some(game) = &mut Game::singleton() { - let player_id = game - .bind() - .find_player_by_addr(&connection.address) - .map(|p| p.id); - if let Some(player_id) = player_id { - peer.broadcast_reliable(Package::PlayerLeft( - game.bind() - .find_player(player_id) - .unwrap() - .clone() - .into(), - )); - game.bind_mut().remove_player(player_id); - } - } - } - teanet::PeerMessage::Closed => { - cli.bind_mut() - .publish_message(format!("Server closed"), CliColor::Info); - self.peer = None; - GameManager::singleton().bind_mut().game = None; - } - 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); - } - } - } - Package::SetReady(_, is_ready) => { - 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() - .update_player_ready(player.id, is_ready); - peer.broadcast_reliable(Package::SetReady( - player.id, is_ready, - )); - } - } - } - Package::MapLoaded => { - if let Some(game) = Game::singleton() { - for player in &game.bind().players { - if let Some(transform) = player.get_transform() { - peer.send_reliable( - &conn.address, - Package::SpawnPlayer(player.id, transform), - ); - } - } - } - } - Package::SelfSync(sync_data) => { - if let Some(game) = &mut Game::singleton() { - if let Some(player) = &mut game - .bind_mut() - .find_player_by_addr_mut(&conn.address) - { - player.apply_self_sync(sync_data); - } - } - } - Package::Jump(_) => { - 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().handle_jump(player.id); - peer.broadcast_reliable(Package::Jump(player.id)); - } - } - } - Package::Shoot(_, to, transform, look_up) => { - if let Some(game) = &mut Game::singleton() { - let player = game - .bind() - .find_player_by_addr(&conn.address) - .cloned(); - if let Some(player) = player { - if game.bind_mut().handle_shoot( - player.id, - to.into(), - transform, - look_up, - true, - ) { - peer.broadcast_reliable(Package::Shoot( - player.id, to, transform, look_up, - )); - } - } - } - } - _ => {} - }, - } - } - } - Err(err) => { - cli.bind_mut() - .publish_message(format!("Error: {}", err), CliColor::Error); - } - }, + while let Some(message) = self.poll() { + self.handle_message(message); } } } } impl NetworkManager { + fn poll(&mut self) -> Option> { + let mut cli = CommandLinePanel::singleton(); + + if let Some(peer) = &mut self.peer { + let peer = match peer { + PeerKind::Client(peer, _) => peer, + PeerKind::Server(peer, _) => peer, + }; + + let result = peer.poll(); + match result { + Ok(msg) => msg, + Err(err) => { + cli.bind_mut() + .publish_message(format!("Error: {}", err), CliColor::Error); + None + } + } + } else { + None + } + } + pub fn singleton() -> Gd { get_autoload_by_name::(NETWORK_SINGLETON_NAME) } @@ -546,7 +218,7 @@ impl NetworkManager { } } - fn swap_to_lobby(&self, is_host: bool) { + pub 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); diff --git a/rust/src/net/protocol.rs b/rust/src/net/protocol.rs new file mode 100644 index 0000000..1e1ea73 --- /dev/null +++ b/rust/src/net/protocol.rs @@ -0,0 +1,310 @@ +use std::net::SocketAddr; + +use teanet::{Peer, PeerMessage}; + +use crate::{ + game_manager::{Game, GameManager}, + net::network_manager::{NetworkManager, Package, PeerKind}, + ui::cli::{CliColor, CommandLinePanel}, +}; + +impl NetworkManager { + pub fn handle_message(&mut self, message: PeerMessage) { + let mut cli = CommandLinePanel::singleton(); + + if let Some(peer) = &mut self.peer { + match peer { + PeerKind::Client(peer, _) => match message { + teanet::PeerMessage::NewConnection(connection) => { + cli.bind_mut().publish_message( + format!("Connected to: {}", connection.address), + CliColor::Info, + ); + self.swap_to_lobby(false); + } + teanet::PeerMessage::Disconnected(connection, connection_error) => { + cli.bind_mut().publish_message( + format!("Disconnected from: {}", connection.address), + CliColor::Info, + ); + if let Some(err) = &connection_error { + cli.bind_mut().publish_message( + format!("Error with connection: {}", err), + CliColor::Error, + ); + } + peer.close(); + } + teanet::PeerMessage::Closed => { + self.peer = None; + GameManager::singleton().bind_mut().game = None; + } + teanet::PeerMessage::Message(_, msg) => match msg { + Package::Hello => { + cli.bind_mut() + .publish_message(format!("Got \"Hello\"!"), CliColor::Info); + } + Package::Players(players, self_id) => { + cli.bind_mut() + .publish_message(format!("Got players"), CliColor::Info); + if let Some(game) = &mut Game::singleton() { + game.bind_mut().set_players( + players.into_iter().map(|p| p.clone().into()).collect(), + ); + game.bind_mut().set_self(self_id); + } + } + Package::SetNick(id, nick) => { + if let Some(game) = &mut Game::singleton() { + if game.bind().self_id != Some(id) { + game.bind_mut().update_player_nick(id, nick); + } + } + } + Package::UpdatePings(pings) => { + if let Some(game) = &mut Game::singleton() { + for (player_id, ping) in pings { + game.bind_mut().update_player_ping(player_id, ping); + } + } + } + Package::NewPlayer(player) => { + if let Some(game) = &mut Game::singleton() { + if player.id != game.bind().self_id.unwrap_or(u16::MAX) { + game.bind_mut().new_player( + SocketAddr::from(([0, 0, 0, 0], 0)), + player.name, + Some(player.id), + ); + } + } + } + Package::PlayerLeft(player) => { + if let Some(game) = &mut Game::singleton() { + if player.id != game.bind().self_id.unwrap_or(u16::MAX) { + game.bind_mut().remove_player(player.id); + } + } + } + Package::SetReady(player_id, is_ready) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().update_player_ready(player_id, is_ready); + } + } + Package::SelectMap(map_id) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().change_map_selection(map_id, true); + } + } + Package::GameStarted => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().start_game(); + } + } + Package::SpawnPlayer(id, transform) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().spawn_player_client(id, transform); + } + } + Package::Sync(sync_data, ball_sync) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().handle_sync(sync_data, ball_sync); + } + } + Package::Jump(player_id) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().handle_jump(player_id); + } + } + Package::Shoot(player_id, to, transform, look_up) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().handle_shoot( + player_id, + to.into(), + transform, + look_up, + false, + ); + } + } + Package::TakeDamage(source_player_id, target_player_id, damage) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().handle_take_damage( + source_player_id, + target_player_id, + damage, + ); + } + } + Package::Kill(source_player_id, target_player_id) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut() + .handle_kill(source_player_id, target_player_id); + } + } + Package::SpawnBall(transform, velocity, player_id) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().spawn_ball( + Some(transform), + Some(velocity), + player_id, + ); + } + } + Package::DespawnBall => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().despawn_ball(); + } + } + Package::SwapWeapon(id, weapon_type) => { + if let Some(game) = &mut Game::singleton() { + game.bind_mut().handle_swap_weapon(id, weapon_type, true); + } + } + _ => {} + }, + }, + PeerKind::Server(peer, _) => match message { + teanet::PeerMessage::NewConnection(connection) => { + cli.bind_mut().publish_message( + format!("Client connected from: {}", connection.address), + CliColor::Info, + ); + + if let Some(game) = &mut Game::singleton() { + let self_id = + game.bind_mut() + .new_player(connection.address, String::new(), None); + peer.send_reliable( + &connection.address, + Package::Players( + game.bind() + .players + .clone() + .into_iter() + .map(|p| p.into()) + .collect(), + self_id, + ), + ); + peer.broadcast_reliable(Package::NewPlayer( + game.bind().find_player(self_id).unwrap().clone().into(), + )); + + peer.send_reliable( + &connection.address, + Package::SelectMap(game.bind().selected_map_idx), + ); + } + } + teanet::PeerMessage::Disconnected(connection, connection_error) => { + cli.bind_mut().publish_message( + format!("Client disconnected: {}", connection.address), + CliColor::Info, + ); + if let Some(err) = &connection_error { + cli.bind_mut().publish_message( + format!("Error with connection: {}", err), + CliColor::Error, + ); + } + if let Some(game) = &mut Game::singleton() { + let player_id = game + .bind() + .find_player_by_addr(&connection.address) + .map(|p| p.id); + if let Some(player_id) = player_id { + peer.broadcast_reliable(Package::PlayerLeft( + game.bind().find_player(player_id).unwrap().clone().into(), + )); + game.bind_mut().remove_player(player_id); + } + } + } + teanet::PeerMessage::Closed => { + cli.bind_mut() + .publish_message(format!("Server closed"), CliColor::Info); + self.peer = None; + GameManager::singleton().bind_mut().game = None; + } + 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); + } + } + } + Package::SetReady(_, is_ready) => { + 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().update_player_ready(player.id, is_ready); + peer.broadcast_reliable(Package::SetReady(player.id, is_ready)); + } + } + } + Package::MapLoaded => { + if let Some(game) = Game::singleton() { + for player in &game.bind().players { + if let Some(transform) = player.get_transform() { + peer.send_reliable( + &conn.address, + Package::SpawnPlayer(player.id, transform), + ); + } + } + } + } + Package::SelfSync(sync_data) => { + if let Some(game) = &mut Game::singleton() { + if let Some(player) = + &mut game.bind_mut().find_player_by_addr_mut(&conn.address) + { + player.apply_self_sync(sync_data); + } + } + } + Package::Jump(_) => { + 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().handle_jump(player.id); + peer.broadcast_reliable(Package::Jump(player.id)); + } + } + } + Package::Shoot(_, to, transform, look_up) => { + if let Some(game) = &mut Game::singleton() { + let player = + game.bind().find_player_by_addr(&conn.address).cloned(); + if let Some(player) = player { + if game.bind_mut().handle_shoot( + player.id, + to.into(), + transform, + look_up, + true, + ) { + peer.broadcast_reliable(Package::Shoot( + player.id, to, transform, look_up, + )); + } + } + } + } + _ => {} + }, + }, + } + } + } +}