rust/hedgewars-server/src/server/core.rs
changeset 14457 98ef2913ec73
parent 14415 06672690d71b
child 14504 6cc0fce249f9
equal deleted inserted replaced
14456:a077aac9df01 14457:98ef2913ec73
     1 use slab;
       
     2 use crate::utils;
       
     3 use super::{
     1 use super::{
       
     2     actions,
       
     3     actions::{Destination, PendingMessage},
       
     4     client::HWClient,
       
     5     coretypes::{ClientId, RoomId},
       
     6     handlers,
     4     io::HWServerIO,
     7     io::HWServerIO,
     5     client::HWClient, room::HWRoom, actions, handlers,
     8     room::HWRoom,
     6     coretypes::{ClientId, RoomId},
       
     7     actions::{Destination, PendingMessage}
       
     8 };
     9 };
     9 use crate::protocol::messages::*;
    10 use crate::protocol::messages::*;
    10 use rand::{RngCore, thread_rng};
    11 use crate::utils;
    11 use base64::{encode};
    12 use base64::encode;
    12 use log::*;
    13 use log::*;
       
    14 use rand::{thread_rng, RngCore};
       
    15 use slab;
    13 
    16 
    14 type Slab<T> = slab::Slab<T>;
    17 type Slab<T> = slab::Slab<T>;
    15 
    18 
    16 pub struct HWServer {
    19 pub struct HWServer {
    17     pub clients: Slab<HWClient>,
    20     pub clients: Slab<HWClient>,
    18     pub rooms: Slab<HWRoom>,
    21     pub rooms: Slab<HWRoom>,
    19     pub lobby_id: RoomId,
    22     pub lobby_id: RoomId,
    20     pub output: Vec<(Vec<ClientId>, HWServerMessage)>,
    23     pub output: Vec<(Vec<ClientId>, HWServerMessage)>,
    21     pub removed_clients: Vec<ClientId>,
    24     pub removed_clients: Vec<ClientId>,
    22     pub io: Box<dyn HWServerIO>
    25     pub io: Box<dyn HWServerIO>,
    23 }
    26 }
    24 
    27 
    25 impl HWServer {
    28 impl HWServer {
    26     pub fn new(clients_limit: usize, rooms_limit: usize, io: Box<dyn HWServerIO>) -> HWServer {
    29     pub fn new(clients_limit: usize, rooms_limit: usize, io: Box<dyn HWServerIO>) -> HWServer {
    27         let rooms = Slab::with_capacity(rooms_limit);
    30         let rooms = Slab::with_capacity(rooms_limit);
    28         let clients = Slab::with_capacity(clients_limit);
    31         let clients = Slab::with_capacity(clients_limit);
    29         let mut server = HWServer {
    32         let mut server = HWServer {
    30             clients, rooms,
    33             clients,
       
    34             rooms,
    31             lobby_id: 0,
    35             lobby_id: 0,
    32             output: vec![],
    36             output: vec![],
    33             removed_clients: vec![],
    37             removed_clients: vec![],
    34             io
    38             io,
    35         };
    39         };
    36         server.lobby_id = server.add_room();
    40         server.lobby_id = server.add_room();
    37         server
    41         server
    38     }
    42     }
    39 
    43 
    46             thread_rng().fill_bytes(&mut salt);
    50             thread_rng().fill_bytes(&mut salt);
    47 
    51 
    48             let client = HWClient::new(entry.key(), encode(&salt));
    52             let client = HWClient::new(entry.key(), encode(&salt));
    49             entry.insert(client);
    53             entry.insert(client);
    50         }
    54         }
    51         self.send(key, &Destination::ToSelf, HWServerMessage::Connected(utils::PROTOCOL_VERSION));
    55         self.send(
       
    56             key,
       
    57             &Destination::ToSelf,
       
    58             HWServerMessage::Connected(utils::PROTOCOL_VERSION),
       
    59         );
    52         key
    60         key
    53     }
    61     }
    54 
    62 
    55     pub fn client_lost(&mut self, client_id: ClientId) {
    63     pub fn client_lost(&mut self, client_id: ClientId) {
    56         actions::run_action(self, client_id,
    64         actions::run_action(
    57                             actions::Action::ByeClient("Connection reset".to_string()));
    65             self,
       
    66             client_id,
       
    67             actions::Action::ByeClient("Connection reset".to_string()),
       
    68         );
    58     }
    69     }
    59 
    70 
    60     pub fn add_room(&mut self) -> RoomId {
    71     pub fn add_room(&mut self) -> RoomId {
    61         let entry = self.rooms.vacant_entry();
    72         let entry = self.rooms.vacant_entry();
    62         let key = entry.key();
    73         let key = entry.key();
    74 
    85 
    75     fn get_recipients(&self, client_id: ClientId, destination: &Destination) -> Vec<ClientId> {
    86     fn get_recipients(&self, client_id: ClientId, destination: &Destination) -> Vec<ClientId> {
    76         let mut ids = match *destination {
    87         let mut ids = match *destination {
    77             Destination::ToSelf => vec![client_id],
    88             Destination::ToSelf => vec![client_id],
    78             Destination::ToId(id) => vec![id],
    89             Destination::ToId(id) => vec![id],
    79             Destination::ToAll {room_id: Some(id), ..} =>
    90             Destination::ToAll {
    80                 self.room_clients(id),
    91                 room_id: Some(id), ..
    81             Destination::ToAll {protocol: Some(proto), ..} =>
    92             } => self.room_clients(id),
    82                 self.protocol_clients(proto),
    93             Destination::ToAll {
    83             Destination::ToAll {..} =>
    94                 protocol: Some(proto),
    84                 self.clients.iter().map(|(id, _)| id).collect::<Vec<_>>()
    95                 ..
       
    96             } => self.protocol_clients(proto),
       
    97             Destination::ToAll { .. } => self.clients.iter().map(|(id, _)| id).collect::<Vec<_>>(),
    85         };
    98         };
    86         if let Destination::ToAll {skip_self: true, ..} = destination {
    99         if let Destination::ToAll {
       
   100             skip_self: true, ..
       
   101         } = destination
       
   102         {
    87             if let Some(index) = ids.iter().position(|id| *id == client_id) {
   103             if let Some(index) = ids.iter().position(|id| *id == client_id) {
    88                 ids.remove(index);
   104                 ids.remove(index);
    89             }
   105             }
    90         }
   106         }
    91         ids
   107         ids
    92     }
   108     }
    93 
   109 
    94     pub fn send(&mut self, client_id: ClientId, destination: &Destination, message: HWServerMessage) {
   110     pub fn send(
       
   111         &mut self,
       
   112         client_id: ClientId,
       
   113         destination: &Destination,
       
   114         message: HWServerMessage,
       
   115     ) {
    95         let ids = self.get_recipients(client_id, &destination);
   116         let ids = self.get_recipients(client_id, &destination);
    96         self.output.push((ids, message));
   117         self.output.push((ids, message));
    97     }
   118     }
    98 
   119 
    99     pub fn react(&mut self, client_id: ClientId, actions: Vec<actions::Action>) {
   120     pub fn react(&mut self, client_id: ClientId, actions: Vec<actions::Action>) {
   100         for action in actions {
   121         for action in actions {
   101             actions::run_action(self, client_id, action);
   122             actions::run_action(self, client_id, action);
   102         }
   123         }
   103     }
   124     }
   104 
   125 
   105     pub fn lobby(&self) -> &HWRoom { &self.rooms[self.lobby_id] }
   126     pub fn lobby(&self) -> &HWRoom {
       
   127         &self.rooms[self.lobby_id]
       
   128     }
   106 
   129 
   107     pub fn has_room(&self, name: &str) -> bool {
   130     pub fn has_room(&self, name: &str) -> bool {
   108         self.rooms.iter().any(|(_, r)| r.name == name)
   131         self.rooms.iter().any(|(_, r)| r.name == name)
   109     }
   132     }
   110 
   133 
   111     pub fn find_room(&self, name: &str) -> Option<&HWRoom> {
   134     pub fn find_room(&self, name: &str) -> Option<&HWRoom> {
   112         self.rooms.iter().find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   135         self.rooms
       
   136             .iter()
       
   137             .find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   113     }
   138     }
   114 
   139 
   115     pub fn find_room_mut(&mut self, name: &str) -> Option<&mut HWRoom> {
   140     pub fn find_room_mut(&mut self, name: &str) -> Option<&mut HWRoom> {
   116         self.rooms.iter_mut().find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   141         self.rooms
       
   142             .iter_mut()
       
   143             .find_map(|(_, r)| Some(r).filter(|r| r.name == name))
   117     }
   144     }
   118 
   145 
   119     pub fn find_client(&self, nick: &str) -> Option<&HWClient> {
   146     pub fn find_client(&self, nick: &str) -> Option<&HWClient> {
   120         self.clients.iter().find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   147         self.clients
       
   148             .iter()
       
   149             .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   121     }
   150     }
   122 
   151 
   123     pub fn find_client_mut(&mut self, nick: &str) -> Option<&mut HWClient> {
   152     pub fn find_client_mut(&mut self, nick: &str) -> Option<&mut HWClient> {
   124         self.clients.iter_mut().find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   153         self.clients
       
   154             .iter_mut()
       
   155             .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick))
   125     }
   156     }
   126 
   157 
   127     pub fn select_clients<F>(&self, f: F) -> Vec<ClientId>
   158     pub fn select_clients<F>(&self, f: F) -> Vec<ClientId>
   128         where F: Fn(&(usize, &HWClient)) -> bool {
   159     where
   129         self.clients.iter().filter(f)
   160         F: Fn(&(usize, &HWClient)) -> bool,
   130             .map(|(_, c)| c.id).collect()
   161     {
       
   162         self.clients.iter().filter(f).map(|(_, c)| c.id).collect()
   131     }
   163     }
   132 
   164 
   133     pub fn room_clients(&self, room_id: RoomId) -> Vec<ClientId> {
   165     pub fn room_clients(&self, room_id: RoomId) -> Vec<ClientId> {
   134         self.select_clients(|(_, c)| c.room_id == Some(room_id))
   166         self.select_clients(|(_, c)| c.room_id == Some(room_id))
   135     }
   167     }
   138         self.select_clients(|(_, c)| c.protocol_number == protocol)
   170         self.select_clients(|(_, c)| c.protocol_number == protocol)
   139     }
   171     }
   140 
   172 
   141     pub fn other_clients_in_room(&self, self_id: ClientId) -> Vec<ClientId> {
   173     pub fn other_clients_in_room(&self, self_id: ClientId) -> Vec<ClientId> {
   142         let room_id = self.clients[self_id].room_id;
   174         let room_id = self.clients[self_id].room_id;
   143         self.select_clients(|(id, c)| *id != self_id && c.room_id == room_id )
   175         self.select_clients(|(id, c)| *id != self_id && c.room_id == room_id)
   144     }
   176     }
   145 
   177 
   146     pub fn client_and_room(&mut self, client_id: ClientId) -> (&mut HWClient, Option<&mut HWRoom>) {
   178     pub fn client_and_room(&mut self, client_id: ClientId) -> (&mut HWClient, Option<&mut HWRoom>) {
   147         let c = &mut self.clients[client_id];
   179         let c = &mut self.clients[client_id];
   148         if let Some(room_id) = c.room_id {
   180         if let Some(room_id) = c.room_id {