quakeball-rust/rust/src/net/protocol.rs
2026-07-22 01:37:19 +03:00

335 lines
17 KiB
Rust

use std::net::SocketAddr;
use teanet::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<Package>) {
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);
}
}
Package::SetTeam(player_id, team) => {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().handle_player_team_change(player_id, team);
}
}
_ => {}
},
},
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,
));
}
}
}
}
Package::SetTeam(player_id, team) => {
if let Some(game) = &mut Game::singleton() {
let self_id = game
.bind()
.find_player_by_addr(&conn.address)
.map(|p| p.id());
if let Some(self_id) = self_id {
if self_id == player_id {
game.bind_mut().try_set_player_team(player_id, team, true);
}
}
}
}
_ => {}
},
},
}
}
}
}