mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
sync TIME ressource to client
- we evaluated multiple ways to sync the time, either store a delta between localtime and ServerTime or just store the ServerTime
This commit is contained in:
parent
a579329005
commit
665e9b9378
@ -39,7 +39,7 @@ use common::{
|
|||||||
mounting::Rider,
|
mounting::Rider,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
recipe::{ComponentRecipeBook, RecipeBook},
|
recipe::{ComponentRecipeBook, RecipeBook},
|
||||||
resources::{GameMode, PlayerEntity, TimeOfDay},
|
resources::{GameMode, PlayerEntity, ServerTime, Time, TimeOfDay},
|
||||||
spiral::Spiral2d,
|
spiral::Spiral2d,
|
||||||
terrain::{
|
terrain::{
|
||||||
block::Block, map::MapConfig, neighbors, site::DungeonKindMeta, BiomeKind,
|
block::Block, map::MapConfig, neighbors, site::DungeonKindMeta, BiomeKind,
|
||||||
@ -1683,7 +1683,6 @@ impl Client {
|
|||||||
&mut self,
|
&mut self,
|
||||||
inputs: ControllerInputs,
|
inputs: ControllerInputs,
|
||||||
dt: Duration,
|
dt: Duration,
|
||||||
total_tick_time: Duration,
|
|
||||||
add_foreign_systems: impl Fn(&mut DispatcherBuilder),
|
add_foreign_systems: impl Fn(&mut DispatcherBuilder),
|
||||||
) -> Result<Vec<Event>, Error> {
|
) -> Result<Vec<Event>, Error> {
|
||||||
span!(_guard, "tick", "Client::tick");
|
span!(_guard, "tick", "Client::tick");
|
||||||
@ -1712,7 +1711,8 @@ impl Client {
|
|||||||
prof_span!("handle and send inputs");
|
prof_span!("handle and send inputs");
|
||||||
self.next_control.inputs = inputs;
|
self.next_control.inputs = inputs;
|
||||||
let con = std::mem::take(&mut self.next_control);
|
let con = std::mem::take(&mut self.next_control);
|
||||||
let rcon = self.local_command_gen.gen(total_tick_time, con);
|
let time = Duration::from_secs_f64(self.state.ecs().read_resource::<Time>().0);
|
||||||
|
let rcon = self.local_command_gen.gen(time, con);
|
||||||
let commands = self
|
let commands = self
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
@ -2178,15 +2178,27 @@ impl Client {
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
prof_span!("handle_server_in_game_msg");
|
prof_span!("handle_server_in_game_msg");
|
||||||
match msg {
|
match msg {
|
||||||
ServerGeneral::AckControl(acked_ids) => {
|
ServerGeneral::TimeSync(time) => {
|
||||||
|
self.state.ecs().write_resource::<ServerTime>().0 = time.0;
|
||||||
|
let latency = self
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.read_storage::<RemoteController>()
|
||||||
|
.get(self.entity())
|
||||||
|
.map(|rc| rc.avg_latency())
|
||||||
|
.unwrap_or_default();
|
||||||
|
self.state.ecs().write_resource::<Time>().0 = time.0 + latency.as_secs_f64();
|
||||||
|
},
|
||||||
|
ServerGeneral::AckControl(acked_ids, time) => {
|
||||||
if let Some(remote_controller) = self
|
if let Some(remote_controller) = self
|
||||||
.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<RemoteController>()
|
.write_storage::<RemoteController>()
|
||||||
.get_mut(self.entity())
|
.get_mut(self.entity())
|
||||||
{
|
{
|
||||||
remote_controller.acked(acked_ids);
|
let time = Duration::from_secs_f64(time.0);
|
||||||
remote_controller.maintain();
|
remote_controller.acked(acked_ids, time);
|
||||||
|
remote_controller.maintain(None);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ServerGeneral::GroupUpdate(change_notification) => {
|
ServerGeneral::GroupUpdate(change_notification) => {
|
||||||
@ -2870,12 +2882,8 @@ mod tests {
|
|||||||
let mut clock = Clock::new(Duration::from_secs_f64(SPT));
|
let mut clock = Clock::new(Duration::from_secs_f64(SPT));
|
||||||
|
|
||||||
//tick
|
//tick
|
||||||
let events_result: Result<Vec<Event>, Error> = client.tick(
|
let events_result: Result<Vec<Event>, Error> =
|
||||||
comp::ControllerInputs::default(),
|
client.tick(comp::ControllerInputs::default(), clock.dt(), |_| {});
|
||||||
clock.dt(),
|
|
||||||
clock.total_tick_time(),
|
|
||||||
|_| {},
|
|
||||||
);
|
|
||||||
|
|
||||||
//chat functionality
|
//chat functionality
|
||||||
client.send_chat("foobar".to_string());
|
client.send_chat("foobar".to_string());
|
||||||
|
@ -142,7 +142,8 @@ pub enum ServerGeneral {
|
|||||||
CharacterSuccess,
|
CharacterSuccess,
|
||||||
SpectatorSuccess(Vec3<f32>),
|
SpectatorSuccess(Vec3<f32>),
|
||||||
//Ingame related
|
//Ingame related
|
||||||
AckControl(HashSet<u64>),
|
TimeSync(Time),
|
||||||
|
AckControl(HashSet<u64>, Time),
|
||||||
GroupUpdate(comp::group::ChangeNotification<Uid>),
|
GroupUpdate(comp::group::ChangeNotification<Uid>),
|
||||||
/// Indicate to the client that they are invited to join a group
|
/// Indicate to the client that they are invited to join a group
|
||||||
Invite {
|
Invite {
|
||||||
@ -316,7 +317,8 @@ impl ServerMsg {
|
|||||||
},
|
},
|
||||||
//Ingame related
|
//Ingame related
|
||||||
ServerGeneral::GroupUpdate(_)
|
ServerGeneral::GroupUpdate(_)
|
||||||
| ServerGeneral::AckControl(_)
|
| ServerGeneral::TimeSync(_)
|
||||||
|
| ServerGeneral::AckControl(_, _)
|
||||||
| ServerGeneral::Invite { .. }
|
| ServerGeneral::Invite { .. }
|
||||||
| ServerGeneral::InvitePending(_)
|
| ServerGeneral::InvitePending(_)
|
||||||
| ServerGeneral::InviteComplete { .. }
|
| ServerGeneral::InviteComplete { .. }
|
||||||
|
@ -19,6 +19,7 @@ pub struct RemoteController {
|
|||||||
commands: ControlCommands,
|
commands: ControlCommands,
|
||||||
existing_commands: HashSet<u64>,
|
existing_commands: HashSet<u64>,
|
||||||
max_hold: Duration,
|
max_hold: Duration,
|
||||||
|
avg_latency: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
@ -29,14 +30,16 @@ pub struct ControlCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RemoteController {
|
impl RemoteController {
|
||||||
/// delte old commands
|
/// delte old and outdated( older than server_time) commands
|
||||||
pub fn maintain(&mut self) {
|
pub fn maintain(&mut self, server_time: Option<Duration>) {
|
||||||
self.commands.make_contiguous();
|
self.commands.make_contiguous();
|
||||||
if let Some(last) = self.commands.back() {
|
if let Some(last) = self.commands.back() {
|
||||||
let min_allowed_age = last.source_time;
|
let min_allowed_age = last.source_time;
|
||||||
|
|
||||||
while let Some(first) = self.commands.front() {
|
while let Some(first) = self.commands.front() {
|
||||||
if first.source_time + self.max_hold < min_allowed_age {
|
if first.source_time + self.max_hold < min_allowed_age
|
||||||
|
|| matches!(server_time, Some(x) if first.source_time < x)
|
||||||
|
{
|
||||||
self.commands
|
self.commands
|
||||||
.pop_front()
|
.pop_front()
|
||||||
.map(|c| self.existing_commands.remove(&c.id));
|
.map(|c| self.existing_commands.remove(&c.id));
|
||||||
@ -87,7 +90,32 @@ impl RemoteController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// arrived at remote and no longer need to be hold locally
|
/// arrived at remote and no longer need to be hold locally
|
||||||
pub fn acked(&mut self, ids: HashSet<u64>) { self.commands.retain(|c| !ids.contains(&c.id)); }
|
pub fn acked(&mut self, ids: HashSet<u64>, server_send_time: Duration) {
|
||||||
|
//get latency from oldest removed command and server_send_time
|
||||||
|
let mut highest_source_time = Duration::from_secs(0);
|
||||||
|
self.commands.retain(|c| {
|
||||||
|
let retain = !ids.contains(&c.id);
|
||||||
|
if !retain && c.source_time > highest_source_time {
|
||||||
|
highest_source_time = c.source_time;
|
||||||
|
}
|
||||||
|
retain
|
||||||
|
});
|
||||||
|
// we add self.avg_latency here as we must assume that highest_source_time was
|
||||||
|
// increased by avg_latency in client TimeSync though we assume that
|
||||||
|
// avg_latency is quite stable and didnt change much between when the component
|
||||||
|
// was added and now
|
||||||
|
if let Some(latency) =
|
||||||
|
(server_send_time + self.avg_latency).checked_sub(highest_source_time)
|
||||||
|
{
|
||||||
|
tracing::error!(?latency, "ggg");
|
||||||
|
self.avg_latency = (99 * self.avg_latency + latency) / 100;
|
||||||
|
} else {
|
||||||
|
// add 5% and 10ms to the latency
|
||||||
|
self.avg_latency =
|
||||||
|
Duration::from_secs_f64(self.avg_latency.as_secs_f64() * 1.05 + 0.01);
|
||||||
|
}
|
||||||
|
tracing::error!(?highest_source_time, ?self.avg_latency, "aaa");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn commands(&self) -> &ControlCommands { &self.commands }
|
pub fn commands(&self) -> &ControlCommands { &self.commands }
|
||||||
|
|
||||||
@ -117,9 +145,6 @@ impl RemoteController {
|
|||||||
Ok(i) => i,
|
Ok(i) => i,
|
||||||
Err(i) => i,
|
Err(i) => i,
|
||||||
};
|
};
|
||||||
println!("start_i {:?}", start_i);
|
|
||||||
println!("end_exclusive_i {:?}", end_exclusive_i);
|
|
||||||
|
|
||||||
if self.commands.is_empty() || end_exclusive_i == start_i {
|
if self.commands.is_empty() || end_exclusive_i == start_i {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -140,8 +165,6 @@ impl RemoteController {
|
|||||||
start + dt
|
start + dt
|
||||||
};
|
};
|
||||||
let local_dur = local_end - local_start;
|
let local_dur = local_end - local_start;
|
||||||
println!("local_start {:?}, local_end {:?}", local_start, local_end);
|
|
||||||
println!("source_time {:?}", e.source_time);
|
|
||||||
result.inputs.move_dir += e.msg.inputs.move_dir * local_dur.as_secs_f32();
|
result.inputs.move_dir += e.msg.inputs.move_dir * local_dur.as_secs_f32();
|
||||||
result.inputs.move_z += e.msg.inputs.move_z * local_dur.as_secs_f32();
|
result.inputs.move_z += e.msg.inputs.move_z * local_dur.as_secs_f32();
|
||||||
look_dir = result.inputs.look_dir.to_vec()
|
look_dir = result.inputs.look_dir.to_vec()
|
||||||
@ -153,6 +176,16 @@ impl RemoteController {
|
|||||||
.break_block_pos
|
.break_block_pos
|
||||||
.or(e.msg.inputs.break_block_pos);
|
.or(e.msg.inputs.break_block_pos);
|
||||||
result.inputs.strafing = result.inputs.strafing || e.msg.inputs.strafing;
|
result.inputs.strafing = result.inputs.strafing || e.msg.inputs.strafing;
|
||||||
|
// we apply events from all that are started here.
|
||||||
|
// if we only are part of 1 tick here we would assume that it was already
|
||||||
|
// covered before
|
||||||
|
if i != start_i || e.source_time >= start {
|
||||||
|
result.actions.append(&mut e.msg.actions.clone());
|
||||||
|
result.events.append(&mut e.msg.events.clone());
|
||||||
|
result
|
||||||
|
.queued_inputs
|
||||||
|
.append(&mut e.msg.queued_inputs.clone());
|
||||||
|
}
|
||||||
last_start = local_start;
|
last_start = local_start;
|
||||||
}
|
}
|
||||||
result.inputs.move_dir /= dt.as_secs_f32();
|
result.inputs.move_dir /= dt.as_secs_f32();
|
||||||
@ -161,6 +194,13 @@ impl RemoteController {
|
|||||||
|
|
||||||
Some(result)
|
Some(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// the average latency is 300ms by default and will be adjusted over time
|
||||||
|
/// with every Ack the server sends its local tick time at the Ack
|
||||||
|
/// so we can calculate how much time was spent for 1 way from
|
||||||
|
/// server->client and assume that this is also true for client->server
|
||||||
|
/// latency
|
||||||
|
pub fn avg_latency(&self) -> Duration { self.avg_latency }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RemoteController {
|
impl Default for RemoteController {
|
||||||
@ -169,6 +209,7 @@ impl Default for RemoteController {
|
|||||||
commands: VecDeque::new(),
|
commands: VecDeque::new(),
|
||||||
existing_commands: HashSet::new(),
|
existing_commands: HashSet::new(),
|
||||||
max_hold: Duration::from_secs(1),
|
max_hold: Duration::from_secs(1),
|
||||||
|
avg_latency: Duration::from_millis(300),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,12 @@ pub struct TimeOfDay(pub f64);
|
|||||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Time(pub f64);
|
pub struct Time(pub f64);
|
||||||
|
|
||||||
|
/// A resource that stores the Server-Time, its needed to calculate the input
|
||||||
|
/// delay and adjust Time on the client keep in mind that it contains a
|
||||||
|
/// network-latency. Only filled on the client
|
||||||
|
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)]
|
||||||
|
pub struct ServerTime(pub f64);
|
||||||
|
|
||||||
/// A resource that stores the time since the previous tick.
|
/// A resource that stores the time since the previous tick.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DeltaTime(pub f32);
|
pub struct DeltaTime(pub f32);
|
||||||
|
@ -13,8 +13,8 @@ use common::{
|
|||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
region::RegionMap,
|
region::RegionMap,
|
||||||
resources::{
|
resources::{
|
||||||
DeltaTime, EntitiesDiedLastTick, GameMode, PlayerEntity, PlayerPhysicsSettings, Time,
|
DeltaTime, EntitiesDiedLastTick, GameMode, PlayerEntity, PlayerPhysicsSettings, ServerTime,
|
||||||
TimeOfDay,
|
Time, TimeOfDay,
|
||||||
},
|
},
|
||||||
slowjob::SlowJobPool,
|
slowjob::SlowJobPool,
|
||||||
terrain::{Block, MapSizeLg, TerrainChunk, TerrainGrid},
|
terrain::{Block, MapSizeLg, TerrainChunk, TerrainGrid},
|
||||||
@ -257,6 +257,7 @@ impl State {
|
|||||||
ecs.insert(Time(0.0));
|
ecs.insert(Time(0.0));
|
||||||
|
|
||||||
// Register unsynced resources used by the ECS.
|
// Register unsynced resources used by the ECS.
|
||||||
|
ecs.insert(ServerTime(0.0)); //synced by msg
|
||||||
ecs.insert(DeltaTime(0.0));
|
ecs.insert(DeltaTime(0.0));
|
||||||
ecs.insert(PlayerEntity(None));
|
ecs.insert(PlayerEntity(None));
|
||||||
ecs.insert(TerrainGrid::new(map_size_lg, default_chunk).unwrap());
|
ecs.insert(TerrainGrid::new(map_size_lg, default_chunk).unwrap());
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{Controller, RemoteController},
|
comp::{Controller, RemoteController},
|
||||||
resources::{Time, DeltaTime,},
|
resources::{DeltaTime, Time},
|
||||||
};
|
};
|
||||||
use common_ecs::{Job, Origin, Phase, System};
|
use common_ecs::{Job, Origin, Phase, System};
|
||||||
use specs::{
|
use specs::{
|
||||||
|
@ -103,7 +103,8 @@ impl Client {
|
|||||||
},
|
},
|
||||||
//In-game related
|
//In-game related
|
||||||
ServerGeneral::GroupUpdate(_)
|
ServerGeneral::GroupUpdate(_)
|
||||||
| ServerGeneral::AckControl(_)
|
| ServerGeneral::TimeSync(_)
|
||||||
|
| ServerGeneral::AckControl(_, _)
|
||||||
| ServerGeneral::Invite { .. }
|
| ServerGeneral::Invite { .. }
|
||||||
| ServerGeneral::InvitePending(_)
|
| ServerGeneral::InvitePending(_)
|
||||||
| ServerGeneral::InviteComplete { .. }
|
| ServerGeneral::InviteComplete { .. }
|
||||||
@ -176,7 +177,8 @@ impl Client {
|
|||||||
},
|
},
|
||||||
//In-game related
|
//In-game related
|
||||||
ServerGeneral::GroupUpdate(_)
|
ServerGeneral::GroupUpdate(_)
|
||||||
| ServerGeneral::AckControl(_)
|
| ServerGeneral::TimeSync(_)
|
||||||
|
| ServerGeneral::AckControl(_, _)
|
||||||
| ServerGeneral::Invite { .. }
|
| ServerGeneral::Invite { .. }
|
||||||
| ServerGeneral::InvitePending(_)
|
| ServerGeneral::InvitePending(_)
|
||||||
| ServerGeneral::InviteComplete { .. }
|
| ServerGeneral::InviteComplete { .. }
|
||||||
|
@ -9,7 +9,7 @@ use common::{
|
|||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
link::Is,
|
link::Is,
|
||||||
mounting::Rider,
|
mounting::Rider,
|
||||||
resources::{PlayerPhysicsSetting, PlayerPhysicsSettings},
|
resources::{PlayerPhysicsSetting, PlayerPhysicsSettings, Time},
|
||||||
slowjob::SlowJobPool,
|
slowjob::SlowJobPool,
|
||||||
terrain::TerrainGrid,
|
terrain::TerrainGrid,
|
||||||
vol::ReadVol,
|
vol::ReadVol,
|
||||||
@ -20,7 +20,7 @@ use common_state::{BlockChange, BuildAreas};
|
|||||||
use core::mem;
|
use core::mem;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage};
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage};
|
||||||
use std::{borrow::Cow, time::Instant};
|
use std::{borrow::Cow, time::Instant, time::Duration};
|
||||||
use tracing::{debug, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -47,6 +47,7 @@ impl Sys {
|
|||||||
fn handle_client_in_game_msg(
|
fn handle_client_in_game_msg(
|
||||||
server_emitter: &mut common::event::Emitter<'_, ServerEvent>,
|
server_emitter: &mut common::event::Emitter<'_, ServerEvent>,
|
||||||
entity: specs::Entity,
|
entity: specs::Entity,
|
||||||
|
time: &Time,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
maybe_presence: &mut Option<&mut Presence>,
|
maybe_presence: &mut Option<&mut Presence>,
|
||||||
terrain: &ReadExpect<'_, TerrainGrid>,
|
terrain: &ReadExpect<'_, TerrainGrid>,
|
||||||
@ -96,9 +97,10 @@ impl Sys {
|
|||||||
ClientGeneral::Control(rc) => {
|
ClientGeneral::Control(rc) => {
|
||||||
if presence.kind.controlling_char() {
|
if presence.kind.controlling_char() {
|
||||||
let ids = remote_controller.append(rc);
|
let ids = remote_controller.append(rc);
|
||||||
remote_controller.maintain();
|
remote_controller.maintain(Some(Duration::from_secs_f64(time.0)));
|
||||||
|
|
||||||
// confirm controls
|
// confirm controls
|
||||||
client.send(ServerGeneral::AckControl(ids))?;
|
client.send(ServerGeneral::AckControl(ids, *time))?;
|
||||||
//Todo: FIXME!!!
|
//Todo: FIXME!!!
|
||||||
/*
|
/*
|
||||||
// Skip respawn if client entity is alive
|
// Skip respawn if client entity is alive
|
||||||
@ -316,6 +318,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
|
Read<'a, Time>,
|
||||||
Read<'a, EventBus<ServerEvent>>,
|
Read<'a, EventBus<ServerEvent>>,
|
||||||
ReadExpect<'a, TerrainGrid>,
|
ReadExpect<'a, TerrainGrid>,
|
||||||
ReadExpect<'a, SlowJobPool>,
|
ReadExpect<'a, SlowJobPool>,
|
||||||
@ -347,6 +350,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
_job: &mut Job<Self>,
|
_job: &mut Job<Self>,
|
||||||
(
|
(
|
||||||
entities,
|
entities,
|
||||||
|
time,
|
||||||
server_event_bus,
|
server_event_bus,
|
||||||
terrain,
|
terrain,
|
||||||
slow_jobs,
|
slow_jobs,
|
||||||
@ -433,6 +437,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
Self::handle_client_in_game_msg(
|
Self::handle_client_in_game_msg(
|
||||||
server_emitter,
|
server_emitter,
|
||||||
entity,
|
entity,
|
||||||
|
&time,
|
||||||
client,
|
client,
|
||||||
&mut clearable_maybe_presence,
|
&mut clearable_maybe_presence,
|
||||||
&terrain,
|
&terrain,
|
||||||
|
@ -5,6 +5,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use common_ecs::{Job, Origin, Phase, System};
|
use common_ecs::{Job, Origin, Phase, System};
|
||||||
use common_net::msg::PingMsg;
|
use common_net::msg::PingMsg;
|
||||||
|
use common_net::msg::ServerGeneral;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use specs::{Entities, ParJoin, Read, WriteStorage};
|
use specs::{Entities, ParJoin, Read, WriteStorage};
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
@ -47,8 +48,10 @@ impl<'a> System<'a> for Sys {
|
|||||||
client.participant.as_mut().map(|p| p.try_fetch_event())
|
client.participant.as_mut().map(|p| p.try_fetch_event())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
client.send_fallible(ServerGeneral::TimeSync(*time));
|
||||||
let res = super::try_recv_all(client, 4, Self::handle_ping_msg);
|
let res = super::try_recv_all(client, 4, Self::handle_ping_msg);
|
||||||
|
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!(?entity, ?e, "network error with client, disconnecting");
|
debug!(?entity, ?e, "network error with client, disconnecting");
|
||||||
|
@ -208,7 +208,6 @@ impl PlayState for CharSelectionState {
|
|||||||
let res = self.client.borrow_mut().tick(
|
let res = self.client.borrow_mut().tick(
|
||||||
comp::ControllerInputs::default(),
|
comp::ControllerInputs::default(),
|
||||||
global_state.clock.dt(),
|
global_state.clock.dt(),
|
||||||
global_state.clock.total_tick_time(),
|
|
||||||
|_| {},
|
|_| {},
|
||||||
);
|
);
|
||||||
match res {
|
match res {
|
||||||
|
@ -226,7 +226,6 @@ impl PlayState for MainMenuState {
|
|||||||
match client.tick(
|
match client.tick(
|
||||||
comp::ControllerInputs::default(),
|
comp::ControllerInputs::default(),
|
||||||
global_state.clock.dt(),
|
global_state.clock.dt(),
|
||||||
global_state.clock.total_tick_time(),
|
|
||||||
|_| {},
|
|_| {},
|
||||||
) {
|
) {
|
||||||
Ok(events) => {
|
Ok(events) => {
|
||||||
|
@ -270,12 +270,7 @@ impl SessionState {
|
|||||||
self.mumble_link.update(player_pos, player_pos);
|
self.mumble_link.update(player_pos, player_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in client.tick(
|
for event in client.tick(self.inputs.clone(), dt, crate::ecs::sys::add_local_systems)? {
|
||||||
self.inputs.clone(),
|
|
||||||
dt,
|
|
||||||
global_state.clock.total_tick_time(),
|
|
||||||
crate::ecs::sys::add_local_systems,
|
|
||||||
)? {
|
|
||||||
match event {
|
match event {
|
||||||
client::Event::Chat(m) => {
|
client::Event::Chat(m) => {
|
||||||
self.hud.new_message(m);
|
self.hud.new_message(m);
|
||||||
|
Loading…
Reference in New Issue
Block a user