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 godot::{classes::CharacterBody3D, prelude::*, tools::get_autoload_by_name};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -6,7 +6,14 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
map::Map,
|
map::Map,
|
||||||
map_resource::MapResource,
|
map_resource::MapResource,
|
||||||
net::network_manager::{NetworkManager, Package, PeerKind},
|
net::{
|
||||||
|
network_manager::{
|
||||||
|
NetworkManager,
|
||||||
|
Package::{self, SelfSync},
|
||||||
|
PeerKind,
|
||||||
|
},
|
||||||
|
util::NetVector3,
|
||||||
|
},
|
||||||
player::{IPlayer, NetPlayerTransform},
|
player::{IPlayer, NetPlayerTransform},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -82,10 +89,52 @@ pub struct Game {
|
|||||||
game_started: bool,
|
game_started: bool,
|
||||||
|
|
||||||
pub current_map: Option<Gd<Map>>,
|
pub current_map: Option<Gd<Map>>,
|
||||||
|
since_last_sync: f64,
|
||||||
|
|
||||||
base: Base<Node>,
|
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]
|
#[godot_api]
|
||||||
impl Game {
|
impl Game {
|
||||||
#[signal]
|
#[signal]
|
||||||
@ -166,6 +215,10 @@ impl Game {
|
|||||||
self.players.iter().find(|p| p.connection_addr == *addr)
|
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> {
|
pub fn find_player(&self, player_id: u16) -> Option<&Player> {
|
||||||
self.players.iter().find(|p| p.id == player_id)
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
@ -260,6 +324,38 @@ impl Player {
|
|||||||
character.dyn_bind_mut().apply_transform(transform);
|
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)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use teanet::{Peer, PeerConfig, PeerMessage, connections::Connection};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
game_manager::{Game, GameManager, NetPlayer, Player},
|
game_manager::{Game, GameManager, NetPlayer, Player},
|
||||||
net::net_stats::Stats,
|
net::{net_stats::Stats, util::NetVector3},
|
||||||
player::NetPlayerTransform,
|
player::NetPlayerTransform,
|
||||||
ui::cli::{CliColor, CommandLinePanel},
|
ui::cli::{CliColor, CommandLinePanel},
|
||||||
};
|
};
|
||||||
@ -217,6 +217,11 @@ impl INode for NetworkManager {
|
|||||||
game.bind_mut().spawn_player(id, transform);
|
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),
|
SelectMap(u8),
|
||||||
GameStarted,
|
GameStarted,
|
||||||
SpawnPlayer(u16, NetPlayerTransform),
|
SpawnPlayer(u16, NetPlayerTransform),
|
||||||
|
Sync(HashMap<u16, (NetVector3, NetPlayerTransform)>),
|
||||||
|
SelfSync(NetVector3, NetVector3),
|
||||||
MapLoaded,
|
MapLoaded,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,8 +23,10 @@ pub trait IPlayer {
|
|||||||
fn get_y_speed(&self) -> f32;
|
fn get_y_speed(&self) -> f32;
|
||||||
fn set_y_speed(&mut self, speed: f32);
|
fn set_y_speed(&mut self, speed: f32);
|
||||||
fn get_movement_dir(&self) -> Vector3;
|
fn get_movement_dir(&self) -> Vector3;
|
||||||
|
fn set_movement_dir(&mut self, dir: Vector3);
|
||||||
fn get_move_speed(&self) -> f32;
|
fn get_move_speed(&self) -> f32;
|
||||||
fn apply_transform(&mut self, transform: NetPlayerTransform);
|
fn apply_transform(&mut self, transform: NetPlayerTransform);
|
||||||
|
fn apply_rotation(&mut self, rot: Vector3);
|
||||||
fn get_transform(&self) -> NetPlayerTransform;
|
fn get_transform(&self) -> NetPlayerTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +97,8 @@ impl IPlayer for LocalPlayer {
|
|||||||
self.movement_dir
|
self.movement_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_movement_dir(&mut self, _dir: Vector3) {}
|
||||||
|
|
||||||
fn get_move_speed(&self) -> f32 {
|
fn get_move_speed(&self) -> f32 {
|
||||||
self.move_speed
|
self.move_speed
|
||||||
}
|
}
|
||||||
@ -106,6 +110,8 @@ impl IPlayer for LocalPlayer {
|
|||||||
.set_global_rotation(transform.rotation.into());
|
.set_global_rotation(transform.rotation.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_rotation(&mut self, _rot: Vector3) {}
|
||||||
|
|
||||||
fn get_transform(&self) -> NetPlayerTransform {
|
fn get_transform(&self) -> NetPlayerTransform {
|
||||||
NetPlayerTransform {
|
NetPlayerTransform {
|
||||||
location: self.base().get_global_position().into(),
|
location: self.base().get_global_position().into(),
|
||||||
@ -212,6 +218,10 @@ impl IPlayer for RemotePlayer {
|
|||||||
self.movement_dir
|
self.movement_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_movement_dir(&mut self, dir: Vector3) {
|
||||||
|
self.movement_dir = dir.into();
|
||||||
|
}
|
||||||
|
|
||||||
fn get_move_speed(&self) -> f32 {
|
fn get_move_speed(&self) -> f32 {
|
||||||
self.move_speed
|
self.move_speed
|
||||||
}
|
}
|
||||||
@ -227,6 +237,10 @@ impl IPlayer for RemotePlayer {
|
|||||||
.set_global_rotation(transform.rotation.into());
|
.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 {
|
fn get_transform(&self) -> NetPlayerTransform {
|
||||||
NetPlayerTransform {
|
NetPlayerTransform {
|
||||||
location: self.base().get_global_position().into(),
|
location: self.base().get_global_position().into(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user