2020-11-02 18:30:56 +00:00
|
|
|
use crate::client::Client;
|
2020-08-07 01:59:28 +00:00
|
|
|
use common::{
|
2021-02-13 23:32:55 +00:00
|
|
|
comp::invite::{Invite, PendingInvites},
|
2020-12-13 17:11:55 +00:00
|
|
|
uid::Uid,
|
2020-08-07 01:59:28 +00:00
|
|
|
};
|
2021-03-08 22:40:02 +00:00
|
|
|
use common_ecs::{Job, Origin, Phase, System};
|
2020-12-13 17:11:55 +00:00
|
|
|
use common_net::msg::{InviteAnswer, ServerGeneral};
|
2021-03-08 08:36:53 +00:00
|
|
|
use specs::{Entities, Join, ReadStorage, WriteStorage};
|
2020-08-07 01:59:28 +00:00
|
|
|
|
2021-02-13 23:32:55 +00:00
|
|
|
/// This system removes timed out invites
|
2021-03-04 14:00:16 +00:00
|
|
|
#[derive(Default)]
|
2020-08-07 01:59:28 +00:00
|
|
|
pub struct Sys;
|
2021-03-08 11:13:59 +00:00
|
|
|
impl<'a> System<'a> for Sys {
|
2021-03-08 08:36:53 +00:00
|
|
|
#[allow(clippy::type_complexity)]
|
2020-08-07 01:59:28 +00:00
|
|
|
type SystemData = (
|
|
|
|
Entities<'a>,
|
|
|
|
WriteStorage<'a, Invite>,
|
|
|
|
WriteStorage<'a, PendingInvites>,
|
2020-11-02 18:30:56 +00:00
|
|
|
ReadStorage<'a, Client>,
|
2020-08-07 01:59:28 +00:00
|
|
|
ReadStorage<'a, Uid>,
|
|
|
|
);
|
|
|
|
|
2021-03-04 14:00:16 +00:00
|
|
|
const NAME: &'static str = "invite_timeout";
|
|
|
|
const ORIGIN: Origin = Origin::Server;
|
|
|
|
const PHASE: Phase = Phase::Create;
|
|
|
|
|
2020-08-07 01:59:28 +00:00
|
|
|
fn run(
|
2021-03-08 11:13:59 +00:00
|
|
|
_job: &mut Job<Self>,
|
2021-03-08 08:36:53 +00:00
|
|
|
(entities, mut invites, mut pending_invites, clients, uids): Self::SystemData,
|
2020-08-07 01:59:28 +00:00
|
|
|
) {
|
|
|
|
let now = std::time::Instant::now();
|
|
|
|
let timed_out_invites = (&entities, &invites)
|
|
|
|
.join()
|
2021-02-11 00:59:14 +00:00
|
|
|
.filter_map(|(invitee, Invite { inviter, kind })| {
|
2020-08-07 01:59:28 +00:00
|
|
|
// Retrieve timeout invite from pending invites
|
|
|
|
let pending = &mut pending_invites.get_mut(*inviter)?.0;
|
|
|
|
let index = pending.iter().position(|p| p.0 == invitee)?;
|
|
|
|
|
|
|
|
// Stop if not timed out
|
2021-02-11 00:59:14 +00:00
|
|
|
if pending[index].2 > now {
|
2020-08-07 01:59:28 +00:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove pending entry
|
|
|
|
pending.swap_remove(index);
|
|
|
|
|
|
|
|
// If no pending invites remain remove the component
|
|
|
|
if pending.is_empty() {
|
|
|
|
pending_invites.remove(*inviter);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inform inviter of timeout
|
2020-11-02 18:30:56 +00:00
|
|
|
if let (Some(client), Some(target)) =
|
|
|
|
(clients.get(*inviter), uids.get(invitee).copied())
|
|
|
|
{
|
|
|
|
client.send_fallible(ServerGeneral::InviteComplete {
|
2020-08-07 01:59:28 +00:00
|
|
|
target,
|
|
|
|
answer: InviteAnswer::TimedOut,
|
2021-02-11 00:59:14 +00:00
|
|
|
kind: *kind,
|
2020-10-16 19:37:28 +00:00
|
|
|
});
|
2020-08-07 01:59:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Some(invitee)
|
|
|
|
})
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
for entity in timed_out_invites {
|
|
|
|
invites.remove(entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|