veloren_server/events/
information.rs

1use crate::client::Client;
2use common::event::RequestSiteInfoEvent;
3use common_net::msg::{ServerGeneral, world_msg::EconomyInfo};
4#[cfg(feature = "plugins")]
5use common_state::plugin::PluginMgr;
6#[cfg(feature = "worldgen")]
7use specs::ReadExpect;
8use specs::{DispatcherBuilder, ReadStorage};
9use std::collections::HashMap;
10#[cfg(feature = "worldgen")]
11use world::IndexOwned;
12
13use super::{ServerEvent, event_dispatch};
14
15pub(super) fn register_event_systems(builder: &mut DispatcherBuilder) {
16    event_dispatch::<RequestSiteInfoEvent>(builder, &[]);
17    #[cfg(feature = "plugins")]
18    event_dispatch::<common::event::RequestPluginsEvent>(builder, &[]);
19}
20
21#[cfg(not(feature = "worldgen"))]
22impl ServerEvent for RequestSiteInfoEvent {
23    type SystemData<'a> = ReadStorage<'a, Client>;
24
25    fn handle(events: impl ExactSizeIterator<Item = Self>, clients: Self::SystemData<'_>) {
26        for ev in events {
27            if let Some(client) = clients.get(ev.entity) {
28                let info = EconomyInfo {
29                    id: ev.id,
30                    population: 0,
31                    stock: HashMap::new(),
32                    labor_values: HashMap::new(),
33                    values: HashMap::new(),
34                    labors: Vec::new(),
35                    last_exports: HashMap::new(),
36                    resources: HashMap::new(),
37                };
38                let msg = ServerGeneral::SiteEconomy(info);
39                client.send_fallible(msg);
40            }
41        }
42    }
43}
44
45#[cfg(feature = "worldgen")]
46impl ServerEvent for RequestSiteInfoEvent {
47    type SystemData<'a> = (ReadExpect<'a, IndexOwned>, ReadStorage<'a, Client>);
48
49    fn handle(events: impl ExactSizeIterator<Item = Self>, (index, clients): Self::SystemData<'_>) {
50        for ev in events {
51            if let Some(client) = clients.get(ev.entity) {
52                let site_id = index.sites.recreate_id(ev.id);
53                let info = if let Some(site_id) = site_id
54                    && let Some(economy) = index.sites.get(site_id).economy.as_ref()
55                {
56                    economy.get_information(site_id)
57                } else {
58                    EconomyInfo {
59                        id: ev.id,
60                        population: 0,
61                        stock: HashMap::new(),
62                        labor_values: HashMap::new(),
63                        values: HashMap::new(),
64                        labors: Vec::new(),
65                        last_exports: HashMap::new(),
66                        resources: HashMap::new(),
67                    }
68                };
69                let msg = ServerGeneral::SiteEconomy(info);
70                client.send_fallible(msg);
71            }
72        }
73    }
74}
75
76/// Send missing plugins to the client
77#[cfg(feature = "plugins")]
78impl ServerEvent for common::event::RequestPluginsEvent {
79    type SystemData<'a> = (ReadExpect<'a, PluginMgr>, ReadStorage<'a, Client>);
80
81    fn handle(
82        events: impl ExactSizeIterator<Item = Self>,
83        (plugin_mgr, clients): Self::SystemData<'_>,
84    ) {
85        for mut ev in events {
86            let Some(client) = clients.get(ev.entity) else {
87                continue;
88            };
89
90            for hash in ev.plugins.drain(..) {
91                if let Some(plugin) = plugin_mgr.find(&hash) {
92                    let buf = Vec::from(plugin.data_buf());
93                    // TODO: @perf We could possibly make this more performant by caching prepared
94                    // messages for each plugin.
95                    client
96                        .send(ServerGeneral::PluginData(buf))
97                        .unwrap_or_else(|e| {
98                            tracing::warn!("Error {e} sending plugin {hash:?} to client")
99                        });
100                }
101            }
102        }
103    }
104}