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