veloren_server/sys/msg/
network_events.rs1use crate::{EditableSettings, client::Client, settings::banlist::NormalizedIpAddr};
2use common::{
3 comp::Player,
4 event::{ClientDisconnectEvent, EventBus},
5};
6use common_ecs::{Job, Origin, Phase, System};
7use common_net::msg::{DisconnectReason, ServerGeneral};
8use network::ParticipantEvent;
9use specs::{Entities, Join, Read, ReadExpect, ReadStorage, WriteStorage};
10
11#[derive(Default)]
23pub struct Sys;
24impl<'a> System<'a> for Sys {
25 type SystemData = (
26 Entities<'a>,
27 ReadStorage<'a, Player>,
28 WriteStorage<'a, Client>,
29 Read<'a, EventBus<ClientDisconnectEvent>>,
30 ReadExpect<'a, EditableSettings>,
31 );
32
33 const NAME: &'static str = "msg::network_events";
34 const ORIGIN: Origin = Origin::Server;
35 const PHASE: Phase = Phase::Create;
36
37 fn run(
38 _job: &mut Job<Self>,
39 (entities, players, mut clients, client_disconnect_event_bus, editable_settings): Self::SystemData,
40 ) {
41 let now = chrono::Utc::now();
42 let mut client_disconnect_emitter = client_disconnect_event_bus.emitter();
43
44 for (entity, client) in (&entities, &mut clients).join() {
45 while let Some(Ok(Some(event))) = client
46 .participant
47 .as_mut()
48 .map(|participant| participant.try_fetch_event())
49 {
50 match event {
51 ParticipantEvent::ChannelCreated(connect_addr) => {
52 if let Some(addr) = connect_addr.socket_addr() {
54 client.current_ip_addrs.push(addr);
55
56 let banned = editable_settings
57 .banlist
58 .ip_bans()
59 .get(&NormalizedIpAddr::from(addr.ip()))
60 .and_then(|ban_entry| ban_entry.current.action.ban())
61 .and_then(|ban| {
62 let admin = players.get(entity).and_then(|player| {
64 editable_settings.admins.get(&player.uuid())
65 });
66 crate::login_provider::ban_applies(ban, admin, now)
67 .then(|| ban.info())
68 });
69
70 if let Some(ban_info) = banned {
71 client_disconnect_emitter.emit(ClientDisconnectEvent(
73 entity,
74 common::comp::DisconnectReason::Kicked,
75 ));
76 let _ = client.send(ServerGeneral::Disconnect(
77 DisconnectReason::Banned(ban_info),
78 ));
79 }
80 }
81 },
82 ParticipantEvent::ChannelDeleted(connect_addr) => {
83 if let Some(addr) = connect_addr.socket_addr() {
85 if let Some(i) = client
86 .current_ip_addrs
87 .iter()
88 .rev()
89 .position(|a| *a == addr)
90 {
91 client.current_ip_addrs.remove(i);
92 } else {
93 tracing::error!(
94 "Channel deleted but its address isn't present in \
95 client.current_ip_addrs!"
96 );
97 }
98 }
99 },
100 }
101 }
102 }
103 }
104}