rust/hedgewars-server/src/core/anteroom.rs
changeset 15521 1fcce8feace4
child 15938 ce47259d5c86
equal deleted inserted replaced
15520:fd3a20e9d095 15521:1fcce8feace4
       
     1 use super::{indexslab::IndexSlab, types::ClientId};
       
     2 use chrono::{offset, DateTime};
       
     3 use std::{iter::Iterator, num::NonZeroU16};
       
     4 
       
     5 pub struct HwAnteroomClient {
       
     6     pub nick: Option<String>,
       
     7     pub protocol_number: Option<NonZeroU16>,
       
     8     pub server_salt: String,
       
     9     pub is_checker: bool,
       
    10     pub is_local_admin: bool,
       
    11     pub is_registered: bool,
       
    12     pub is_admin: bool,
       
    13     pub is_contributor: bool,
       
    14 }
       
    15 
       
    16 struct Ipv4AddrRange {
       
    17     min: [u8; 4],
       
    18     max: [u8; 4],
       
    19 }
       
    20 
       
    21 impl Ipv4AddrRange {
       
    22     fn contains(&self, addr: [u8; 4]) -> bool {
       
    23         (0..4).all(|i| self.min[i] <= addr[i] && addr[i] <= self.max[i])
       
    24     }
       
    25 }
       
    26 
       
    27 struct BanCollection {
       
    28     ban_ips: Vec<Ipv4AddrRange>,
       
    29     ban_timeouts: Vec<DateTime<offset::Utc>>,
       
    30     ban_reasons: Vec<String>,
       
    31 }
       
    32 
       
    33 impl BanCollection {
       
    34     fn new() -> Self {
       
    35         Self {
       
    36             ban_ips: vec![],
       
    37             ban_timeouts: vec![],
       
    38             ban_reasons: vec![],
       
    39         }
       
    40     }
       
    41 
       
    42     fn find(&self, addr: [u8; 4]) -> Option<String> {
       
    43         let time = offset::Utc::now();
       
    44         self.ban_ips
       
    45             .iter()
       
    46             .enumerate()
       
    47             .find(|(i, r)| r.contains(addr) && time < self.ban_timeouts[*i])
       
    48             .map(|(i, _)| self.ban_reasons[i].clone())
       
    49     }
       
    50 }
       
    51 
       
    52 pub struct HwAnteroom {
       
    53     pub clients: IndexSlab<HwAnteroomClient>,
       
    54     bans: BanCollection,
       
    55 }
       
    56 
       
    57 impl HwAnteroom {
       
    58     pub fn new(clients_limit: usize) -> Self {
       
    59         let clients = IndexSlab::with_capacity(clients_limit);
       
    60         HwAnteroom {
       
    61             clients,
       
    62             bans: BanCollection::new(),
       
    63         }
       
    64     }
       
    65 
       
    66     pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> {
       
    67         self.bans.find(addr)
       
    68     }
       
    69 
       
    70     pub fn add_client(&mut self, client_id: ClientId, salt: String, is_local_admin: bool) {
       
    71         let client = HwAnteroomClient {
       
    72             nick: None,
       
    73             protocol_number: None,
       
    74             server_salt: salt,
       
    75             is_checker: false,
       
    76             is_local_admin,
       
    77             is_registered: false,
       
    78             is_admin: false,
       
    79             is_contributor: false,
       
    80         };
       
    81         self.clients.insert(client_id, client);
       
    82     }
       
    83 
       
    84     pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteroomClient> {
       
    85         let client = self.clients.remove(client_id);
       
    86         client
       
    87     }
       
    88 }