force update counter

This commit is contained in:
IsseW 2022-07-31 23:01:10 +02:00
parent a165bc09bc
commit 87821d5c1d
13 changed files with 89 additions and 49 deletions

View File

@ -217,6 +217,7 @@ pub struct Client {
available_recipes: HashMap<String, Option<SpriteKind>>,
lod_zones: HashMap<Vec2<i32>, lod::Zone>,
lod_last_requested: Option<Instant>,
force_update_counter: u64,
max_group_size: u32,
// Client has received an invite (inviter uid, time out instant)
@ -679,6 +680,8 @@ impl Client {
lod_zones: HashMap::new(),
lod_last_requested: None,
force_update_counter: 0,
max_group_size,
invite: None,
group_leader: None,
@ -1754,8 +1757,12 @@ impl Client {
self.state.read_storage().get(self.entity()).cloned(),
self.state.read_storage().get(self.entity()).cloned(),
) {
self.in_game_stream
.send(ClientGeneral::PlayerPhysics { pos, vel, ori })?;
self.in_game_stream.send(ClientGeneral::PlayerPhysics {
pos,
vel,
ori,
force_counter: self.force_update_counter,
})?;
}
}
@ -2071,7 +2078,8 @@ impl Client {
.ecs_mut()
.apply_entity_sync_package(entity_sync_package);
},
ServerGeneral::CompSync(comp_sync_package) => {
ServerGeneral::CompSync(comp_sync_package, force_counter) => {
self.force_update_counter = force_counter;
self.state
.ecs_mut()
.apply_comp_sync_package(comp_sync_package);

View File

@ -74,6 +74,7 @@ pub enum ClientGeneral {
pos: comp::Pos,
vel: comp::Vel,
ori: comp::Ori,
force_counter: u64,
},
UnlockSkill(Skill),
UnlockSkillGroup(SkillGroupKind),

View File

@ -188,7 +188,7 @@ pub enum ServerGeneral {
SetPlayerEntity(Uid),
TimeOfDay(TimeOfDay, Calendar),
EntitySync(sync::EntitySyncPackage),
CompSync(sync::CompSyncPackage<EcsCompPacket>),
CompSync(sync::CompSyncPackage<EcsCompPacket>, u64),
CreateEntity(sync::EntityPackage<EcsCompPacket>),
DeleteEntity(Uid),
Disconnect(DisconnectReason),
@ -327,7 +327,7 @@ impl ServerMsg {
| ServerGeneral::SetPlayerEntity(_)
| ServerGeneral::TimeOfDay(_, _)
| ServerGeneral::EntitySync(_)
| ServerGeneral::CompSync(_)
| ServerGeneral::CompSync(_, _)
| ServerGeneral::CreateEntity(_)
| ServerGeneral::DeleteEntity(_)
| ServerGeneral::Disconnect(_)

View File

@ -213,9 +213,32 @@ impl Component for PhysicsState {
/// Used to forcefully update the position, velocity, and orientation of the
/// client
#[derive(Copy, Clone, Debug, Default)]
pub struct ForceUpdate;
#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct ForceUpdate {
flag: bool,
counter: u64,
}
impl ForceUpdate {
pub fn forced() -> Self {
Self {
flag: true,
counter: 0,
}
}
pub fn update(&mut self) {
self.flag = true;
self.counter = self.counter.wrapping_add(1);
}
pub fn clear(&mut self) { self.flag = false; }
pub fn is_forced(&self) -> bool { self.flag }
pub fn counter(&self) -> u64 { self.counter }
}
impl Component for ForceUpdate {
type Storage = NullStorage<Self>;
type Storage = VecStorage<Self>;
}

View File

@ -148,7 +148,9 @@ impl Link for Mounting {
.map(|p| p.0.map(|e| e.floor()))
.unwrap_or_else(|| terrain.find_space(old_pos).map(|e| e as f32))
+ Vec3::new(0.5, 0.5, 0.0);
let _ = force_update.insert(rider, comp::ForceUpdate);
if let Some(force_update) = force_update.get_mut(rider) {
force_update.update();
}
});
}
}

View File

@ -206,7 +206,7 @@ impl Client {
| ServerGeneral::SetPlayerEntity(_)
| ServerGeneral::TimeOfDay(_, _)
| ServerGeneral::EntitySync(_)
| ServerGeneral::CompSync(_)
| ServerGeneral::CompSync(_, _)
| ServerGeneral::CreateEntity(_)
| ServerGeneral::DeleteEntity(_)
| ServerGeneral::Disconnect(_)

View File

@ -257,11 +257,12 @@ fn position_mut<T>(
{
server.notify_client(entity, ServerGeneral::SpectatePosition(pos));
} else {
let _ = server
server
.state
.ecs()
.write_storage::<comp::ForceUpdate>()
.insert(entity, comp::ForceUpdate);
.get_mut(entity)
.map(|force_update| force_update.update());
}
}
res
@ -2077,7 +2078,7 @@ fn handle_light(
.ecs_mut()
.create_entity_synced()
.with(pos)
.with(comp::ForceUpdate)
.with(comp::ForceUpdate::forced())
.with(light_emitter);
if let Some(light_offset) = light_offset_opt {
builder.with(light_offset).build();

View File

@ -410,10 +410,9 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
.map(|e| error!(?e, ?entity, "Failed to set zero vel on dead client"));
state
.ecs()
.write_storage()
.insert(entity, comp::ForceUpdate)
.err()
.map(|e| error!(?e, ?entity, "Failed to insert ForceUpdate on dead client"));
.write_storage::<comp::ForceUpdate>()
.get_mut(entity)
.map(|force_update| force_update.update());
state
.ecs()
.write_storage::<Energy>()
@ -648,15 +647,14 @@ pub fn handle_respawn(server: &Server, entity: EcsEntity) {
.map(|pos| pos.0 = respawn_point);
state
.ecs()
.write_storage()
.insert(entity, comp::ForceUpdate)
.err()
.map(|e| {
error!(
?e,
"Error inserting ForceUpdate component when respawning client"
)
});
.write_storage::<comp::PhysicsState>()
.get_mut(entity)
.map(|phys_state| phys_state.reset());
state
.ecs()
.write_storage::<comp::ForceUpdate>()
.get_mut(entity)
.map(|force_update| force_update.update());
}
}
@ -1259,15 +1257,9 @@ pub fn handle_teleport_to(server: &Server, entity: EcsEntity, target: Uid, max_r
if let (Some(pos), Some(target_pos)) = (positions.get_mut(entity), target_pos) {
if max_range.map_or(true, |r| pos.0.distance_squared(target_pos.0) < r.powi(2)) {
*pos = target_pos;
ecs.write_storage()
.insert(entity, comp::ForceUpdate)
.err()
.map(|e| {
error!(
?e,
"Error inserting ForceUpdate component when teleporting client"
)
});
ecs.write_storage::<comp::ForceUpdate>()
.get_mut(entity)
.map(|force_update| force_update.update());
}
}
}

View File

@ -486,7 +486,7 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possessee_uid: Ui
possessee,
);
if !comp_sync_package.is_empty() {
client.send_fallible(ServerGeneral::CompSync(comp_sync_package));
client.send_fallible(ServerGeneral::CompSync(comp_sync_package, 0)); // TODO: Check if this should be zero
}
}

View File

@ -510,7 +510,7 @@ impl StateExt for State {
self.write_component_ignore_entity_dead(entity, comp::Combo::default());
// Make sure physics components are updated
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate);
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced());
const INITIAL_VD: u32 = 5; //will be changed after login
self.write_component_ignore_entity_dead(
@ -536,7 +536,7 @@ impl StateExt for State {
self.write_component_ignore_entity_dead(entity, comp::Pos(spawn_point));
// Make sure physics components are updated
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate);
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced());
const INITIAL_VD: u32 = 5; //will be changed after login
self.write_component_ignore_entity_dead(
@ -604,7 +604,7 @@ impl StateExt for State {
self.write_component_ignore_entity_dead(entity, waypoint);
self.write_component_ignore_entity_dead(entity, comp::Pos(waypoint.get_pos()));
self.write_component_ignore_entity_dead(entity, comp::Vel(Vec3::zero()));
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate);
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced());
}
if let Some(map_marker) = map_marker {

View File

@ -208,12 +208,15 @@ impl<'a> System<'a> for Sys {
// We lazily initialize the the synchronization messages in case there are no
// clients.
let mut entity_comp_sync = Either::Left((entity_sync_package, comp_sync_package));
for (client, _, _, _) in &mut subscribers {
for (client, _, client_entity, _) in &mut subscribers {
let msg = entity_comp_sync.right_or_else(
|(entity_sync_package, comp_sync_package)| {
(
client.prepare(ServerGeneral::EntitySync(entity_sync_package)),
client.prepare(ServerGeneral::CompSync(comp_sync_package)),
client.prepare(ServerGeneral::CompSync(
comp_sync_package,
force_updates.get(*client_entity).map_or(0, |f| f.counter()),
)),
)
},
);
@ -234,7 +237,7 @@ impl<'a> System<'a> for Sys {
(&positions, last_pos.mask().maybe()),
(&velocities, last_vel.mask().maybe()).maybe(),
(&orientations, last_vel.mask().maybe()).maybe(),
force_updates.mask().maybe(),
force_updates.maybe(),
colliders.maybe(),
)
.join()
@ -250,7 +253,7 @@ impl<'a> System<'a> for Sys {
// Don't send client physics updates about itself unless force update is
// set or the client is subject to
// server-authoritative physics
force_update.is_some()
force_update.map_or(false, |f| f.is_forced())
|| player_physics_setting.server_authoritative()
|| is_rider.get(entity).is_some()
} else if matches!(collider, Some(Collider::Voxel { .. })) {
@ -305,7 +308,10 @@ impl<'a> System<'a> for Sys {
}
}
client.send_fallible(ServerGeneral::CompSync(comp_sync_package));
client.send_fallible(ServerGeneral::CompSync(
comp_sync_package,
force_updates.get(*client_entity).map_or(0, |f| f.counter()),
));
}
},
);
@ -363,7 +369,10 @@ impl<'a> System<'a> for Sys {
let comp_sync_package =
trackers.create_sync_from_client_package(&tracked_storages, entity);
if !comp_sync_package.is_empty() {
client.send_fallible(ServerGeneral::CompSync(comp_sync_package));
client.send_fallible(ServerGeneral::CompSync(
comp_sync_package,
force_updates.get(entity).map_or(0, |f| f.counter()),
));
}
}
@ -392,7 +401,9 @@ impl<'a> System<'a> for Sys {
}
// Remove all force flags.
force_updates.clear();
for force_update in (&mut force_updates).join() {
force_update.clear();
}
inventory_updates.clear();
// Sync resources

View File

@ -111,7 +111,7 @@ impl Sys {
}
}
},
ClientGeneral::PlayerPhysics { pos, vel, ori } => {
ClientGeneral::PlayerPhysics { pos, vel, ori, force_counter } => {
let player_physics_setting = maybe_player.map(|p| {
player_physics_settings
.settings
@ -120,7 +120,7 @@ impl Sys {
});
if presence.kind.controlling_char()
&& force_updates.get(entity).is_none()
&& force_updates.get(entity).map_or(true, |force_update| force_update.counter() == force_counter)
&& healths.get(entity).map_or(true, |h| !h.is_dead)
&& is_rider.get(entity).is_none()
&& player_physics_setting

View File

@ -243,7 +243,9 @@ impl<'a> System<'a> for Sys {
.map(|x| x.as_::<f32>())
.unwrap_or_else(|| chunk.find_accessible_pos(pos.0.xy().as_::<i32>(), false));
repositioned.push(entity);
let _ = force_update.insert(entity, ForceUpdate);
force_update
.get_mut(entity)
.map(|force_update| force_update.update());
let _ = waypoints.insert(entity, Waypoint::new(pos.0, *time));
}
}