Implement syncing
This commit is contained in:
parent
4b0a90be0e
commit
1402b10180
@ -1,4 +1,4 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::{collections::HashMap, net::SocketAddr};
|
||||
|
||||
use godot::{classes::CharacterBody3D, prelude::*, tools::get_autoload_by_name};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -6,7 +6,14 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
map::Map,
|
||||
map_resource::MapResource,
|
||||
net::network_manager::{NetworkManager, Package, PeerKind},
|
||||
net::{
|
||||
network_manager::{
|
||||
NetworkManager,
|
||||
Package::{self, SelfSync},
|
||||
PeerKind,
|
||||
},
|
||||
util::NetVector3,
|
||||
},
|
||||
player::{IPlayer, NetPlayerTransform},
|
||||
};
|
||||
|
||||
@ -82,10 +89,52 @@ pub struct Game {
|
||||
game_started: bool,
|
||||
|
||||
pub current_map: Option<Gd<Map>>,
|
||||
since_last_sync: f64,
|
||||
|
||||
base: Base<Node>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl INode for Game {
|
||||
fn process(&mut self, delta: f64) {
|
||||
self.since_last_sync += delta;
|
||||
if self.since_last_sync > (1. / 30.) {
|
||||
self.since_last_sync = 0.;
|
||||
if let Some(_) = self.current_map {
|
||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||
match peer {
|
||||
PeerKind::Client(peer, socket_addr) => {
|
||||
if let Some(player) = self
|
||||
.players
|
||||
.iter()
|
||||
.find(|p| p.id == self.self_id.unwrap_or(0))
|
||||
{
|
||||
if let Some((dir, rot)) = &player.get_self_sync() {
|
||||
peer.send_unreliable(
|
||||
socket_addr,
|
||||
SelfSync(dir.clone(), rot.clone()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
PeerKind::Server(peer, _) => {
|
||||
let mut sync_data = HashMap::new();
|
||||
for player in &self.players {
|
||||
if let (Some(dir), Some(transform)) =
|
||||
(player.get_move_dir(), player.get_transform())
|
||||
{
|
||||
sync_data.insert(player.id, (dir, transform));
|
||||
}
|
||||
}
|
||||
peer.broadcast_unreliable(Package::Sync(sync_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl Game {
|
||||
#[signal]
|
||||
@ -166,6 +215,10 @@ impl Game {
|
||||
self.players.iter().find(|p| p.connection_addr == *addr)
|
||||
}
|
||||
|
||||
pub fn find_player_by_addr_mut(&mut self, addr: &SocketAddr) -> Option<&mut Player> {
|
||||
self.players.iter_mut().find(|p| p.connection_addr == *addr)
|
||||
}
|
||||
|
||||
pub fn find_player(&self, player_id: u16) -> Option<&Player> {
|
||||
self.players.iter().find(|p| p.id == player_id)
|
||||
}
|
||||
@ -234,6 +287,17 @@ impl Game {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_sync(&mut self, sync_data: HashMap<u16, (NetVector3, NetPlayerTransform)>) {
|
||||
for (player_id, (dir, transform)) in sync_data {
|
||||
if let Some(player) = self.players.iter_mut().find(|p| p.id == player_id) {
|
||||
if player.id != self.self_id.unwrap_or(0) {
|
||||
player.set_transform(transform);
|
||||
player.set_move_dir(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -260,6 +324,38 @@ impl Player {
|
||||
character.dyn_bind_mut().apply_transform(transform);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_move_dir(&self) -> Option<NetVector3> {
|
||||
if let Some(character) = &self.character {
|
||||
Some(character.dyn_bind().get_movement_dir().into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_move_dir(&mut self, dir: NetVector3) {
|
||||
if let Some(character) = &mut self.character {
|
||||
character.dyn_bind_mut().set_movement_dir(dir.into());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_self_sync(&self) -> Option<(NetVector3, NetVector3)> {
|
||||
if let Some(character) = &self.character {
|
||||
Some((
|
||||
character.dyn_bind().get_movement_dir().into(),
|
||||
character.dyn_bind().get_transform().rotation,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_self_sync(&mut self, dir: NetVector3, rot: NetVector3) {
|
||||
if let Some(character) = &mut self.character {
|
||||
character.dyn_bind_mut().set_movement_dir(dir.into());
|
||||
character.dyn_bind_mut().apply_rotation(rot.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
|
||||
@ -10,7 +10,7 @@ use teanet::{Peer, PeerConfig, PeerMessage, connections::Connection};
|
||||
|
||||
use crate::{
|
||||
game_manager::{Game, GameManager, NetPlayer, Player},
|
||||
net::net_stats::Stats,
|
||||
net::{net_stats::Stats, util::NetVector3},
|
||||
player::NetPlayerTransform,
|
||||
ui::cli::{CliColor, CommandLinePanel},
|
||||
};
|
||||
@ -217,6 +217,11 @@ impl INode for NetworkManager {
|
||||
game.bind_mut().spawn_player(id, transform);
|
||||
}
|
||||
}
|
||||
Package::Sync(sync_data) => {
|
||||
if let Some(game) = &mut Game::singleton() {
|
||||
game.bind_mut().handle_sync(sync_data);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
@ -346,6 +351,16 @@ impl INode for NetworkManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
Package::SelfSync(dir, rot) => {
|
||||
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(dir, rot);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
@ -466,6 +481,8 @@ pub enum Package {
|
||||
SelectMap(u8),
|
||||
GameStarted,
|
||||
SpawnPlayer(u16, NetPlayerTransform),
|
||||
Sync(HashMap<u16, (NetVector3, NetPlayerTransform)>),
|
||||
SelfSync(NetVector3, NetVector3),
|
||||
MapLoaded,
|
||||
}
|
||||
|
||||
|
||||
@ -23,8 +23,10 @@ pub trait IPlayer {
|
||||
fn get_y_speed(&self) -> f32;
|
||||
fn set_y_speed(&mut self, speed: f32);
|
||||
fn get_movement_dir(&self) -> Vector3;
|
||||
fn set_movement_dir(&mut self, dir: Vector3);
|
||||
fn get_move_speed(&self) -> f32;
|
||||
fn apply_transform(&mut self, transform: NetPlayerTransform);
|
||||
fn apply_rotation(&mut self, rot: Vector3);
|
||||
fn get_transform(&self) -> NetPlayerTransform;
|
||||
}
|
||||
|
||||
@ -95,6 +97,8 @@ impl IPlayer for LocalPlayer {
|
||||
self.movement_dir
|
||||
}
|
||||
|
||||
fn set_movement_dir(&mut self, _dir: Vector3) {}
|
||||
|
||||
fn get_move_speed(&self) -> f32 {
|
||||
self.move_speed
|
||||
}
|
||||
@ -106,6 +110,8 @@ impl IPlayer for LocalPlayer {
|
||||
.set_global_rotation(transform.rotation.into());
|
||||
}
|
||||
|
||||
fn apply_rotation(&mut self, _rot: Vector3) {}
|
||||
|
||||
fn get_transform(&self) -> NetPlayerTransform {
|
||||
NetPlayerTransform {
|
||||
location: self.base().get_global_position().into(),
|
||||
@ -212,6 +218,10 @@ impl IPlayer for RemotePlayer {
|
||||
self.movement_dir
|
||||
}
|
||||
|
||||
fn set_movement_dir(&mut self, dir: Vector3) {
|
||||
self.movement_dir = dir.into();
|
||||
}
|
||||
|
||||
fn get_move_speed(&self) -> f32 {
|
||||
self.move_speed
|
||||
}
|
||||
@ -227,6 +237,10 @@ impl IPlayer for RemotePlayer {
|
||||
.set_global_rotation(transform.rotation.into());
|
||||
}
|
||||
|
||||
fn apply_rotation(&mut self, rot: Vector3) {
|
||||
self.base_mut().set_global_rotation(rot);
|
||||
}
|
||||
|
||||
fn get_transform(&self) -> NetPlayerTransform {
|
||||
NetPlayerTransform {
|
||||
location: self.base().get_global_position().into(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user