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 site = index.sites.get(site_id);
55                    site.economy.get_information(site_id)
56                } else {
57                    EconomyInfo {
58                        id: ev.id,
59                        population: 0,
60                        stock: HashMap::new(),
61                        labor_values: HashMap::new(),
62                        values: HashMap::new(),
63                        labors: Vec::new(),
64                        last_exports: HashMap::new(),
65                        resources: HashMap::new(),
66                    }
67                };
68                let msg = ServerGeneral::SiteEconomy(info);
69                client.send_fallible(msg);
70            }
71        }
72    }
73}
74
75/// Send missing plugins to the client
76#[cfg(feature = "plugins")]
77impl ServerEvent for common::event::RequestPluginsEvent {
78    type SystemData<'a> = (ReadExpect<'a, PluginMgr>, ReadStorage<'a, Client>);
79
80    fn handle(
81        events: impl ExactSizeIterator<Item = Self>,
82        (plugin_mgr, clients): Self::SystemData<'_>,
83    ) {
84        for mut ev in events {
85            let Some(client) = clients.get(ev.entity) else {
86                continue;
87            };
88
89            for hash in ev.plugins.drain(..) {
90                if let Some(plugin) = plugin_mgr.find(&hash) {
91                    let buf = Vec::from(plugin.data_buf());
92                    // TODO: @perf We could possibly make this more performant by caching prepared
93                    // messages for each plugin.
94                    client
95                        .send(ServerGeneral::PluginData(buf))
96                        .unwrap_or_else(|e| {
97                            tracing::warn!("Error {e} sending plugin {hash:?} to client")
98                        });
99                }
100            }
101        }
102    }
103}