veloren_server/sys/
chunk_send.rs

1use crate::{chunk_serialize::SerializedChunk, client::Client, metrics::NetworkRequestMetrics};
2
3use common_ecs::{Job, Origin, Phase, System};
4use specs::{ReadExpect, ReadStorage};
5
6/// This system will handle sending terrain to clients by
7/// collecting chunks that need to be send for a single generation run and then
8/// trigger a SlowJob for serialisation.
9#[derive(Default)]
10pub struct Sys;
11impl<'a> System<'a> for Sys {
12    type SystemData = (
13        ReadStorage<'a, Client>,
14        ReadExpect<'a, NetworkRequestMetrics>,
15        ReadExpect<'a, crossbeam_channel::Receiver<SerializedChunk>>,
16    );
17
18    const NAME: &'static str = "chunk_send";
19    const ORIGIN: Origin = Origin::Server;
20    const PHASE: Phase = Phase::Create;
21
22    fn run(_job: &mut Job<Self>, (clients, network_metrics, chunk_receiver): Self::SystemData) {
23        let mut lossy = 0u64;
24        let mut lossless = 0u64;
25        for sc in chunk_receiver.try_iter() {
26            for recipient in sc.recipients {
27                if let Some(client) = clients.get(recipient) {
28                    if client.send_prepared(&sc.msg).is_err() {
29                        if sc.lossy_compression {
30                            lossy += 1;
31                        } else {
32                            lossless += 1;
33                        }
34                    }
35                }
36            }
37        }
38        network_metrics.chunks_served_lossy.inc_by(lossy);
39        network_metrics.chunks_served_lossless.inc_by(lossless);
40    }
41}