rust/hedgewars-server/src/core/anteroom.rs
changeset 16120 5febd2bc5372
parent 16018 fb389df02e3e
equal deleted inserted replaced
16119:278533359a93 16120:5febd2bc5372
     1 use super::{indexslab::IndexSlab, types::ClientId};
     1 use super::{indexslab::IndexSlab, types::ClientId};
       
     2 use crate::core::client::HwClient;
       
     3 use crate::core::digest::Sha1Digest;
     2 use chrono::{offset, DateTime};
     4 use chrono::{offset, DateTime};
       
     5 use std::collections::{HashMap, HashSet};
     3 use std::{iter::Iterator, num::NonZeroU16};
     6 use std::{iter::Iterator, num::NonZeroU16};
     4 
     7 
     5 pub struct HwAnteroomClient {
     8 pub struct HwAnteroomClient {
     6     pub nick: Option<String>,
     9     pub nick: Option<String>,
     7     pub protocol_number: Option<NonZeroU16>,
    10     pub protocol_number: Option<NonZeroU16>,
    49             .map(|(i, _)| self.ban_reasons[i].clone())
    52             .map(|(i, _)| self.ban_reasons[i].clone())
    50     }
    53     }
    51 }
    54 }
    52 
    55 
    53 pub struct HwAnteroom {
    56 pub struct HwAnteroom {
    54     pub clients: IndexSlab<HwAnteroomClient>,
    57     clients: IndexSlab<HwAnteroomClient>,
    55     bans: BanCollection,
    58     bans: BanCollection,
       
    59     taken_nicks: HashSet<String>,
       
    60     reconnection_tokens: HashMap<String, String>,
    56 }
    61 }
    57 
    62 
    58 impl HwAnteroom {
    63 impl HwAnteroom {
    59     pub fn new(clients_limit: usize) -> Self {
    64     pub fn new(clients_limit: usize) -> Self {
    60         let clients = IndexSlab::with_capacity(clients_limit);
    65         let clients = IndexSlab::with_capacity(clients_limit);
    61         HwAnteroom {
    66         HwAnteroom {
    62             clients,
    67             clients,
    63             bans: BanCollection::new(),
    68             bans: BanCollection::new(),
       
    69             taken_nicks: Default::default(),
       
    70             reconnection_tokens: Default::default(),
    64         }
    71         }
    65     }
    72     }
    66 
    73 
    67     pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> {
    74     pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> {
    68         self.bans.find(addr)
    75         self.bans.find(addr)
    80             is_contributor: false,
    87             is_contributor: false,
    81         };
    88         };
    82         self.clients.insert(client_id, client);
    89         self.clients.insert(client_id, client);
    83     }
    90     }
    84 
    91 
       
    92     pub fn has_client(&self, id: ClientId) -> bool {
       
    93         self.clients.contains(id)
       
    94     }
       
    95 
       
    96     pub fn get_client(&mut self, id: ClientId) -> &HwAnteroomClient {
       
    97         &self.clients[id]
       
    98     }
       
    99 
       
   100     pub fn get_client_mut(&mut self, id: ClientId) -> &mut HwAnteroomClient {
       
   101         &mut self.clients[id]
       
   102     }
       
   103 
    85     pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteroomClient> {
   104     pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteroomClient> {
    86         let client = self.clients.remove(client_id);
   105         let client = self.clients.remove(client_id);
       
   106         if let Some(HwAnteroomClient {
       
   107             nick: Some(nick), ..
       
   108         }) = &client
       
   109         {
       
   110             self.taken_nicks.remove(nick);
       
   111         }
    87         client
   112         client
    88     }
   113     }
       
   114 
       
   115     pub fn nick_taken(&self, nick: &str) -> bool {
       
   116         self.taken_nicks.contains(nick)
       
   117     }
       
   118 
       
   119     pub fn remember_nick(&mut self, nick: String) {
       
   120         self.taken_nicks.insert(nick);
       
   121     }
       
   122 
       
   123     pub fn forget_nick(&mut self, nick: &str) {
       
   124         self.taken_nicks.remove(nick);
       
   125     }
       
   126 
       
   127     #[inline]
       
   128     pub fn get_nick_token(&self, nick: &str) -> Option<&str> {
       
   129         self.reconnection_tokens.get(nick).map(|s| &s[..])
       
   130     }
       
   131 
       
   132     #[inline]
       
   133     pub fn register_nick_token(&mut self, nick: &str) -> Option<&str> {
       
   134         if self.reconnection_tokens.contains_key(nick) {
       
   135             None
       
   136         } else {
       
   137             let token = format!("{:x}", Sha1Digest::random());
       
   138             self.reconnection_tokens.insert(nick.to_string(), token);
       
   139             Some(&self.reconnection_tokens[nick])
       
   140         }
       
   141     }
    89 }
   142 }