veloren_server/events/
mod.rs

1use std::{marker::PhantomData, sync::Arc};
2
3use crate::{Server, state_ext::StateExt};
4use common::event::{
5    ChatEvent, ClientDisconnectEvent, ClientDisconnectWithoutPersistenceEvent, CommandEvent,
6    EventBus, ExitIngameEvent,
7};
8use common_base::span;
9use specs::{
10    DispatcherBuilder, Entity as EcsEntity, ReadExpect, WorldExt, WriteExpect,
11    shred::SendDispatcher,
12};
13
14use self::{
15    entity_creation::{
16        handle_create_aura_entity, handle_create_item_drop, handle_create_npc,
17        handle_create_object, handle_create_ship, handle_create_special_entity,
18        handle_initialize_character, handle_initialize_spectator, handle_loaded_character_data,
19        handle_shockwave, handle_shoot,
20    },
21    entity_manipulation::{handle_delete, handle_start_interaction, handle_transform},
22    interaction::handle_tame_pet,
23    mounting::{handle_mount, handle_mount_volume, handle_unmount},
24    player::{
25        handle_character_delete, handle_client_disconnect, handle_exit_ingame, handle_possess,
26    },
27    trade::handle_process_trade_action,
28};
29
30mod entity_creation;
31mod entity_manipulation;
32mod group_manip;
33mod information;
34mod interaction;
35mod inventory_manip;
36mod invite;
37mod mounting;
38mod player;
39mod trade;
40
41/// Shared utilities used by other code **in this crate**
42pub(crate) mod shared {
43    pub(crate) use super::{
44        entity_manipulation::{TransformEntityError, transform_entity},
45        group_manip::update_map_markers,
46        trade::cancel_trades_for,
47    };
48}
49
50pub trait ServerEvent: Send + Sync + 'static {
51    type SystemData<'a>: specs::SystemData<'a>;
52
53    const NAME: &'static str = std::any::type_name::<Self>();
54
55    fn handle(events: impl ExactSizeIterator<Item = Self>, data: Self::SystemData<'_>);
56}
57
58struct EventHandler<T>(PhantomData<T>);
59impl<T> Default for EventHandler<T> {
60    fn default() -> Self { Self(PhantomData) }
61}
62
63impl<'a, T: ServerEvent> common_ecs::System<'a> for EventHandler<T> {
64    type SystemData = (
65        ReadExpect<'a, crate::metrics::ServerEventMetrics>,
66        WriteExpect<'a, EventBus<T>>,
67        T::SystemData<'a>,
68    );
69
70    const NAME: &'static str = T::NAME;
71    const ORIGIN: common_ecs::Origin = common_ecs::Origin::Server;
72    const PHASE: common_ecs::Phase = common_ecs::Phase::Apply;
73
74    fn run(_job: &mut common_ecs::Job<Self>, (metrics, mut ev, data): Self::SystemData) {
75        span!(guard, "Recv events");
76        let events = ev.recv_all_mut();
77        drop(guard);
78
79        span!(guard, "Add metrics for event");
80        metrics
81            .event_count
82            .with_label_values(&[T::NAME])
83            .inc_by(events.len() as u64);
84        drop(guard);
85
86        span!(guard, "Handle events");
87        T::handle(events, data);
88        drop(guard);
89    }
90}
91
92fn event_dispatch<T: ServerEvent>(builder: &mut DispatcherBuilder, dependencies: &[&str]) {
93    common_ecs::dispatch::<EventHandler<T>>(builder, dependencies);
94}
95
96fn event_sys_name<T: ServerEvent>() -> String {
97    <EventHandler<T> as common_ecs::System>::sys_name()
98}
99
100pub fn register_event_systems(builder: &mut DispatcherBuilder) {
101    inventory_manip::register_event_systems(builder);
102    entity_manipulation::register_event_systems(builder);
103    interaction::register_event_systems(builder);
104    invite::register_event_systems(builder);
105    group_manip::register_event_systems(builder);
106    information::register_event_systems(builder);
107}
108
109pub enum Event {
110    ClientConnected {
111        entity: EcsEntity,
112    },
113    ClientDisconnected {
114        entity: EcsEntity,
115    },
116    Chat {
117        entity: Option<EcsEntity>,
118        msg: String,
119    },
120}
121
122impl Server {
123    fn handle_serial_events<T: Send + 'static, F: FnMut(&mut Self, T)>(&mut self, mut f: F) {
124        if let Some(bus) = self.state.ecs_mut().get_mut::<EventBus<T>>() {
125            let events = bus.recv_all_mut();
126            let server_event_metrics = self
127                .state
128                .ecs()
129                .read_resource::<crate::metrics::ServerEventMetrics>();
130            server_event_metrics
131                .event_count
132                .with_label_values(&[std::any::type_name::<T>()])
133                .inc_by(events.len() as u64);
134            drop(server_event_metrics);
135
136            for ev in events {
137                f(self, ev)
138            }
139        }
140    }
141
142    fn handle_all_serial_events(&mut self, frontend_events: &mut Vec<Event>) {
143        self.handle_serial_events(handle_initialize_character);
144        self.handle_serial_events(handle_initialize_spectator);
145        self.handle_serial_events(handle_loaded_character_data);
146        self.handle_serial_events(|this, ev| {
147            handle_create_npc(this, ev);
148        });
149        self.handle_serial_events(handle_create_ship);
150        self.handle_serial_events(handle_shoot);
151        self.handle_serial_events(handle_shockwave);
152        self.handle_serial_events(handle_create_special_entity);
153        self.handle_serial_events(handle_create_item_drop);
154        self.handle_serial_events(handle_create_object);
155        self.handle_serial_events(handle_create_aura_entity);
156        self.handle_serial_events(handle_delete);
157
158        self.handle_serial_events(handle_character_delete);
159        self.handle_serial_events(|this, ev: ExitIngameEvent| {
160            handle_exit_ingame(this, ev.entity, false)
161        });
162        self.handle_serial_events(|this, ev: ClientDisconnectEvent| {
163            handle_client_disconnect(this, ev.0, ev.1, false);
164        });
165        self.handle_serial_events(|this, ev: ClientDisconnectEvent| {
166            frontend_events.push(handle_client_disconnect(this, ev.0, ev.1, false));
167        });
168        self.handle_serial_events(|this, ev: ClientDisconnectWithoutPersistenceEvent| {
169            frontend_events.push(handle_client_disconnect(
170                this,
171                ev.0,
172                common::comp::DisconnectReason::Kicked,
173                true,
174            ));
175        });
176        self.handle_serial_events(handle_possess);
177        self.handle_serial_events(handle_transform);
178        self.handle_serial_events(handle_start_interaction);
179        self.handle_serial_events(|this, ev: CommandEvent| {
180            this.process_command(ev.0, ev.1, ev.2);
181        });
182        self.handle_serial_events(|this, ev: ChatEvent| {
183            this.state.send_chat(ev.0);
184        });
185        self.handle_serial_events(handle_mount);
186        self.handle_serial_events(handle_mount_volume);
187        self.handle_serial_events(handle_unmount);
188        self.handle_serial_events(handle_tame_pet);
189        self.handle_serial_events(handle_process_trade_action);
190    }
191
192    pub fn handle_events(&mut self) -> Vec<Event> {
193        let mut frontend_events = Vec::new();
194
195        span!(guard, "run event systems");
196        // This dispatches all the systems in parallel.
197        self.event_dispatcher.dispatch(self.state.ecs());
198        drop(guard);
199
200        span!(guard, "handle serial events");
201        self.handle_all_serial_events(&mut frontend_events);
202        drop(guard);
203
204        self.state.maintain_ecs();
205
206        frontend_events
207    }
208
209    pub fn create_event_dispatcher(pools: Arc<rayon::ThreadPool>) -> SendDispatcher<'static> {
210        span!(_guard, "create event dispatcher");
211        // Run systems to handle events.
212        // Create and run a dispatcher for ecs systems.
213        let mut dispatch_builder = DispatcherBuilder::new().with_pool(pools);
214        register_event_systems(&mut dispatch_builder);
215        dispatch_builder
216            .build()
217            .try_into_sendable()
218            .ok()
219            .expect("This should be sendable")
220    }
221}