rust/hedgewars-server/src/core/server.rs
changeset 15542 fd3a20e9d095
parent 15541 b3157d218ae2
child 15544 4a0b06b03199
equal deleted inserted replaced
15541:b3157d218ae2 15542:fd3a20e9d095
     1 use super::{
     1 use super::{
       
     2     anteroom::HwAnteroomClient,
     2     client::HwClient,
     3     client::HwClient,
     3     indexslab::IndexSlab,
     4     indexslab::IndexSlab,
     4     room::HwRoom,
     5     room::HwRoom,
     5     types::{ClientId, RoomId, ServerVar, TeamInfo},
     6     types::{ClientId, RoomId, ServerVar, TeamInfo},
     6 };
     7 };
     7 use crate::{protocol::messages::HwProtocolMessage::Greeting, utils};
     8 use crate::{protocol::messages::HwProtocolMessage::Greeting, utils};
     8 
     9 
     9 use bitflags::_core::hint::unreachable_unchecked;
    10 use bitflags::_core::hint::unreachable_unchecked;
    10 use bitflags::*;
    11 use bitflags::*;
    11 use chrono::{offset, DateTime};
       
    12 use log::*;
    12 use log::*;
    13 use slab::Slab;
    13 use slab::Slab;
    14 use std::{borrow::BorrowMut, collections::HashSet, iter, mem::replace, num::NonZeroU16};
    14 use std::{borrow::BorrowMut, collections::HashSet, iter, mem::replace};
    15 
    15 
    16 #[derive(Debug)]
    16 #[derive(Debug)]
    17 pub enum CreateRoomError {
    17 pub enum CreateRoomError {
    18     InvalidName,
    18     InvalidName,
    19     AlreadyExists,
    19     AlreadyExists,
   104 #[derive(Debug)]
   104 #[derive(Debug)]
   105 pub struct UninitializedError();
   105 pub struct UninitializedError();
   106 #[derive(Debug)]
   106 #[derive(Debug)]
   107 pub struct AccessError();
   107 pub struct AccessError();
   108 
   108 
   109 pub struct HwAnteClient {
       
   110     pub nick: Option<String>,
       
   111     pub protocol_number: Option<NonZeroU16>,
       
   112     pub server_salt: String,
       
   113     pub is_checker: bool,
       
   114     pub is_local_admin: bool,
       
   115     pub is_registered: bool,
       
   116     pub is_admin: bool,
       
   117     pub is_contributor: bool,
       
   118 }
       
   119 
       
   120 struct Ipv4AddrRange {
       
   121     min: [u8; 4],
       
   122     max: [u8; 4],
       
   123 }
       
   124 
       
   125 impl Ipv4AddrRange {
       
   126     fn contains(&self, addr: [u8; 4]) -> bool {
       
   127         (0..4).all(|i| self.min[i] <= addr[i] && addr[i] <= self.max[i])
       
   128     }
       
   129 }
       
   130 
       
   131 struct BanCollection {
       
   132     ban_ips: Vec<Ipv4AddrRange>,
       
   133     ban_timeouts: Vec<DateTime<offset::Utc>>,
       
   134     ban_reasons: Vec<String>,
       
   135 }
       
   136 
       
   137 impl BanCollection {
       
   138     fn new() -> Self {
       
   139         Self {
       
   140             ban_ips: vec![],
       
   141             ban_timeouts: vec![],
       
   142             ban_reasons: vec![],
       
   143         }
       
   144     }
       
   145 
       
   146     fn find(&self, addr: [u8; 4]) -> Option<String> {
       
   147         let time = offset::Utc::now();
       
   148         self.ban_ips
       
   149             .iter()
       
   150             .enumerate()
       
   151             .find(|(i, r)| r.contains(addr) && time < self.ban_timeouts[*i])
       
   152             .map(|(i, _)| self.ban_reasons[i].clone())
       
   153     }
       
   154 }
       
   155 
       
   156 pub struct HwAnteroom {
       
   157     pub clients: IndexSlab<HwAnteClient>,
       
   158     bans: BanCollection,
       
   159 }
       
   160 
       
   161 impl HwAnteroom {
       
   162     pub fn new(clients_limit: usize) -> Self {
       
   163         let clients = IndexSlab::with_capacity(clients_limit);
       
   164         HwAnteroom {
       
   165             clients,
       
   166             bans: BanCollection::new(),
       
   167         }
       
   168     }
       
   169 
       
   170     pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> {
       
   171         self.bans.find(addr)
       
   172     }
       
   173 
       
   174     pub fn add_client(&mut self, client_id: ClientId, salt: String, is_local_admin: bool) {
       
   175         let client = HwAnteClient {
       
   176             nick: None,
       
   177             protocol_number: None,
       
   178             server_salt: salt,
       
   179             is_checker: false,
       
   180             is_local_admin,
       
   181             is_registered: false,
       
   182             is_admin: false,
       
   183             is_contributor: false,
       
   184         };
       
   185         self.clients.insert(client_id, client);
       
   186     }
       
   187 
       
   188     pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteClient> {
       
   189         let client = self.clients.remove(client_id);
       
   190         client
       
   191     }
       
   192 }
       
   193 
       
   194 pub struct ServerGreetings {
   109 pub struct ServerGreetings {
   195     pub for_latest_protocol: String,
   110     pub for_latest_protocol: String,
   196     pub for_old_protocols: String,
   111     pub for_old_protocols: String,
   197 }
   112 }
   198 
   113 
   210         const REGISTERED_ONLY = 0b0000_1000;
   125         const REGISTERED_ONLY = 0b0000_1000;
   211     }
   126     }
   212 }
   127 }
   213 
   128 
   214 pub struct HwServer {
   129 pub struct HwServer {
   215     pub clients: IndexSlab<HwClient>,
   130     clients: IndexSlab<HwClient>,
   216     pub rooms: Slab<HwRoom>,
   131     pub rooms: Slab<HwRoom>,
   217     pub anteroom: HwAnteroom,
       
   218     pub latest_protocol: u16,
   132     pub latest_protocol: u16,
   219     pub flags: ServerFlags,
   133     pub flags: ServerFlags,
   220     pub greetings: ServerGreetings,
   134     pub greetings: ServerGreetings,
   221 }
   135 }
   222 
   136 
   225         let rooms = Slab::with_capacity(rooms_limit);
   139         let rooms = Slab::with_capacity(rooms_limit);
   226         let clients = IndexSlab::with_capacity(clients_limit);
   140         let clients = IndexSlab::with_capacity(clients_limit);
   227         Self {
   141         Self {
   228             clients,
   142             clients,
   229             rooms,
   143             rooms,
   230             anteroom: HwAnteroom::new(clients_limit),
       
   231             greetings: ServerGreetings::new(),
   144             greetings: ServerGreetings::new(),
   232             latest_protocol: 58,
   145             latest_protocol: 58,
   233             flags: ServerFlags::empty(),
   146             flags: ServerFlags::empty(),
   234         }
   147         }
   235     }
   148     }
   284             .get(client_id)
   197             .get(client_id)
   285             .map(|c| c.is_admin())
   198             .map(|c| c.is_admin())
   286             .unwrap_or(false)
   199             .unwrap_or(false)
   287     }
   200     }
   288 
   201 
   289     pub fn add_client(&mut self, client_id: ClientId, data: HwAnteClient) {
   202     pub fn add_client(&mut self, client_id: ClientId, data: HwAnteroomClient) {
   290         if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) {
   203         if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) {
   291             let mut client = HwClient::new(client_id, protocol.get(), nick);
   204             let mut client = HwClient::new(client_id, protocol.get(), nick);
   292             client.set_is_checker(data.is_checker);
   205             client.set_is_checker(data.is_checker);
   293             #[cfg(not(feature = "official-server"))]
   206             #[cfg(not(feature = "official-server"))]
   294             client.set_is_admin(data.is_local_admin);
   207             client.set_is_admin(data.is_local_admin);