rust/hedgewars-server/src/core/server.rs
changeset 15080 e935b1ad23f3
parent 15079 c5a6e8566425
child 15181 f6115638aa92
equal deleted inserted replaced
15079:c5a6e8566425 15080:e935b1ad23f3
     1 use super::{
     1 use super::{
     2     client::HWClient,
     2     client::HwClient,
       
     3     indexslab::IndexSlab,
       
     4     room::HwRoom,
     3     types::{ClientId, RoomId},
     5     types::{ClientId, RoomId},
     4     indexslab::IndexSlab,
       
     5     room::HWRoom,
       
     6 };
     6 };
     7 use crate::{
     7 use crate::{protocol::messages::HwProtocolMessage::Greeting, utils};
     8     utils,
       
     9     protocol::messages::HWProtocolMessage::Greeting
       
    10 };
       
    11 
     8 
    12 use bitflags::*;
     9 use bitflags::*;
    13 use log::*;
    10 use log::*;
    14 use slab;
    11 use slab;
    15 use std::{borrow::BorrowMut, iter, num::NonZeroU16};
    12 use std::{borrow::BorrowMut, iter, num::NonZeroU16};
    16 
    13 
    17 type Slab<T> = slab::Slab<T>;
    14 type Slab<T> = slab::Slab<T>;
    18 
    15 
    19 pub struct HWAnteClient {
    16 pub struct HwAnteClient {
    20     pub nick: Option<String>,
    17     pub nick: Option<String>,
    21     pub protocol_number: Option<NonZeroU16>,
    18     pub protocol_number: Option<NonZeroU16>,
    22     pub server_salt: String,
    19     pub server_salt: String,
    23     pub is_checker: bool,
    20     pub is_checker: bool,
    24 }
    21 }
    25 
    22 
    26 pub struct HWAnteroom {
    23 pub struct HwAnteroom {
    27     pub clients: IndexSlab<HWAnteClient>,
    24     pub clients: IndexSlab<HwAnteClient>,
    28 }
    25 }
    29 
    26 
    30 impl HWAnteroom {
    27 impl HwAnteroom {
    31     pub fn new(clients_limit: usize) -> Self {
    28     pub fn new(clients_limit: usize) -> Self {
    32         let clients = IndexSlab::with_capacity(clients_limit);
    29         let clients = IndexSlab::with_capacity(clients_limit);
    33         HWAnteroom { clients }
    30         HwAnteroom { clients }
    34     }
    31     }
    35 
    32 
    36     pub fn add_client(&mut self, client_id: ClientId, salt: String) {
    33     pub fn add_client(&mut self, client_id: ClientId, salt: String) {
    37         let client = HWAnteClient {
    34         let client = HwAnteClient {
    38             nick: None,
    35             nick: None,
    39             protocol_number: None,
    36             protocol_number: None,
    40             server_salt: salt,
    37             server_salt: salt,
    41             is_checker: false,
    38             is_checker: false,
    42         };
    39         };
    43         self.clients.insert(client_id, client);
    40         self.clients.insert(client_id, client);
    44     }
    41     }
    45 
    42 
    46     pub fn remove_client(&mut self, client_id: ClientId) -> Option<HWAnteClient> {
    43     pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteClient> {
    47         let mut client = self.clients.remove(client_id);
    44         let mut client = self.clients.remove(client_id);
    48         client
    45         client
    49     }
    46     }
    50 }
    47 }
    51 
    48 
    67     pub struct ServerFlags: u8 {
    64     pub struct ServerFlags: u8 {
    68         const REGISTERED_ONLY = 0b0000_1000;
    65         const REGISTERED_ONLY = 0b0000_1000;
    69     }
    66     }
    70 }
    67 }
    71 
    68 
    72 pub struct HWServer {
    69 pub struct HwServer {
    73     pub clients: IndexSlab<HWClient>,
    70     pub clients: IndexSlab<HwClient>,
    74     pub rooms: Slab<HWRoom>,
    71     pub rooms: Slab<HwRoom>,
    75     pub anteroom: HWAnteroom,
    72     pub anteroom: HwAnteroom,
    76     pub latest_protocol: u16,
    73     pub latest_protocol: u16,
    77     pub flags: ServerFlags,
    74     pub flags: ServerFlags,
    78     pub greetings: ServerGreetings,
    75     pub greetings: ServerGreetings,
    79 }
    76 }
    80 
    77 
    81 impl HWServer {
    78 impl HwServer {
    82     pub fn new(clients_limit: usize, rooms_limit: usize) -> Self {
    79     pub fn new(clients_limit: usize, rooms_limit: usize) -> Self {
    83         let rooms = Slab::with_capacity(rooms_limit);
    80         let rooms = Slab::with_capacity(rooms_limit);
    84         let clients = IndexSlab::with_capacity(clients_limit);
    81         let clients = IndexSlab::with_capacity(clients_limit);
    85         Self {
    82         Self {
    86             clients,
    83             clients,
    87             rooms,
    84             rooms,
    88             anteroom: HWAnteroom::new(clients_limit),
    85             anteroom: HwAnteroom::new(clients_limit),
    89             greetings: ServerGreetings::new(),
    86             greetings: ServerGreetings::new(),
    90             latest_protocol: 58,
    87             latest_protocol: 58,
    91             flags: ServerFlags::empty(),
    88             flags: ServerFlags::empty(),
    92         }
    89         }
    93     }
    90     }
    94 
    91 
    95     pub fn add_client(&mut self, client_id: ClientId, data: HWAnteClient) {
    92     pub fn add_client(&mut self, client_id: ClientId, data: HwAnteClient) {
    96         if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) {
    93         if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) {
    97             let mut client = HWClient::new(client_id, protocol.get(), nick);
    94             let mut client = HwClient::new(client_id, protocol.get(), nick);
    98             client.set_is_checker(data.is_checker);
    95             client.set_is_checker(data.is_checker);
    99             self.clients.insert(client_id, client);
    96             self.clients.insert(client_id, client);
   100         }
    97         }
   101     }
    98     }
   102 
    99 
   134 
   131 
   135     pub fn has_room(&self, name: &str) -> bool {
   132     pub fn has_room(&self, name: &str) -> bool {
   136         self.find_room(name).is_some()
   133         self.find_room(name).is_some()
   137     }
   134     }
   138 
   135 
   139     pub fn find_room(&self, name: &str) -> Option<&HWRoom> {
   136     pub fn find_room(&self, name: &str) -> Option<&HwRoom> {
   140         self.rooms
   137         self.rooms
   141             .iter()
   138             .iter()
   142             .find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   139             .find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   143     }
   140     }
   144 
   141 
   145     pub fn find_room_mut(&mut self, name: &str) -> Option<&mut HWRoom> {
   142     pub fn find_room_mut(&mut self, name: &str) -> Option<&mut HwRoom> {
   146         self.rooms
   143         self.rooms
   147             .iter_mut()
   144             .iter_mut()
   148             .find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   145             .find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   149     }
   146     }
   150 
   147 
   151     pub fn find_client(&self, nick: &str) -> Option<&HWClient> {
   148     pub fn find_client(&self, nick: &str) -> Option<&HwClient> {
   152         self.clients
   149         self.clients
   153             .iter()
   150             .iter()
   154             .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   151             .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   155     }
   152     }
   156 
   153 
   157     pub fn find_client_mut(&mut self, nick: &str) -> Option<&mut HWClient> {
   154     pub fn find_client_mut(&mut self, nick: &str) -> Option<&mut HwClient> {
   158         self.clients
   155         self.clients
   159             .iter_mut()
   156             .iter_mut()
   160             .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   157             .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   161     }
   158     }
   162 
   159 
   164         self.clients.iter().map(|(id, _)| id)
   161         self.clients.iter().map(|(id, _)| id)
   165     }
   162     }
   166 
   163 
   167     pub fn filter_clients<'a, F>(&'a self, f: F) -> impl Iterator<Item = ClientId> + 'a
   164     pub fn filter_clients<'a, F>(&'a self, f: F) -> impl Iterator<Item = ClientId> + 'a
   168     where
   165     where
   169         F: Fn(&(usize, &HWClient)) -> bool + 'a,
   166         F: Fn(&(usize, &HwClient)) -> bool + 'a,
   170     {
   167     {
   171         self.clients.iter().filter(f).map(|(_, c)| c.id)
   168         self.clients.iter().filter(f).map(|(_, c)| c.id)
   172     }
   169     }
   173 
   170 
   174     pub fn filter_rooms<'a, F>(&'a self, f: F) -> impl Iterator<Item = RoomId> + 'a
   171     pub fn filter_rooms<'a, F>(&'a self, f: F) -> impl Iterator<Item = RoomId> + 'a
   175     where
   172     where
   176         F: Fn(&(usize, &HWRoom)) -> bool + 'a,
   173         F: Fn(&(usize, &HwRoom)) -> bool + 'a,
   177     {
   174     {
   178         self.rooms.iter().filter(f).map(|(_, c)| c.id)
   175         self.rooms.iter().filter(f).map(|(_, c)| c.id)
   179     }
   176     }
   180 
   177 
   181     pub fn collect_clients<F>(&self, f: F) -> Vec<ClientId>
   178     pub fn collect_clients<F>(&self, f: F) -> Vec<ClientId>
   182     where
   179     where
   183         F: Fn(&(usize, &HWClient)) -> bool,
   180         F: Fn(&(usize, &HwClient)) -> bool,
   184     {
   181     {
   185         self.filter_clients(f).collect()
   182         self.filter_clients(f).collect()
   186     }
   183     }
   187 
   184 
   188     pub fn collect_nicks<F>(&self, f: F) -> Vec<String>
   185     pub fn collect_nicks<F>(&self, f: F) -> Vec<String>
   189     where
   186     where
   190         F: Fn(&(usize, &HWClient)) -> bool,
   187         F: Fn(&(usize, &HwClient)) -> bool,
   191     {
   188     {
   192         self.clients
   189         self.clients
   193             .iter()
   190             .iter()
   194             .filter(f)
   191             .filter(f)
   195             .map(|(_, c)| c.nick.clone())
   192             .map(|(_, c)| c.nick.clone())
   224     pub fn set_is_registered_only(&mut self, value: bool) {
   221     pub fn set_is_registered_only(&mut self, value: bool) {
   225         self.flags.set(ServerFlags::REGISTERED_ONLY, value)
   222         self.flags.set(ServerFlags::REGISTERED_ONLY, value)
   226     }
   223     }
   227 }
   224 }
   228 
   225 
   229 fn allocate_room(rooms: &mut Slab<HWRoom>) -> &mut HWRoom {
   226 fn allocate_room(rooms: &mut Slab<HwRoom>) -> &mut HwRoom {
   230     let entry = rooms.vacant_entry();
   227     let entry = rooms.vacant_entry();
   231     let room = HWRoom::new(entry.key());
   228     let room = HwRoom::new(entry.key());
   232     entry.insert(room)
   229     entry.insert(room)
   233 }
   230 }
   234 
   231 
   235 fn create_room(
   232 fn create_room(
   236     client: &mut HWClient,
   233     client: &mut HwClient,
   237     rooms: &mut Slab<HWRoom>,
   234     rooms: &mut Slab<HwRoom>,
   238     name: String,
   235     name: String,
   239     password: Option<String>,
   236     password: Option<String>,
   240 ) -> RoomId {
   237 ) -> RoomId {
   241     let room = allocate_room(rooms);
   238     let room = allocate_room(rooms);
   242 
   239 
   254     client.set_is_joined_mid_game(false);
   251     client.set_is_joined_mid_game(false);
   255 
   252 
   256     room.id
   253     room.id
   257 }
   254 }
   258 
   255 
   259 fn move_to_room(client: &mut HWClient, room: &mut HWRoom) {
   256 fn move_to_room(client: &mut HwClient, room: &mut HwRoom) {
   260     debug_assert!(client.room_id != Some(room.id));
   257     debug_assert!(client.room_id != Some(room.id));
   261 
   258 
   262     room.players_number += 1;
   259     room.players_number += 1;
   263 
   260 
   264     client.room_id = Some(room.id);
   261     client.room_id = Some(room.id);