rust/hedgewars-server/src/server/core.rs
changeset 14509 6cc0fce249f9
parent 14462 98ef2913ec73
child 14676 455865ccd36c
equal deleted inserted replaced
14508:831ecafd74c6 14509:6cc0fce249f9
    11 use crate::utils;
    11 use crate::utils;
    12 use base64::encode;
    12 use base64::encode;
    13 use log::*;
    13 use log::*;
    14 use rand::{thread_rng, RngCore};
    14 use rand::{thread_rng, RngCore};
    15 use slab;
    15 use slab;
       
    16 use std::borrow::BorrowMut;
    16 
    17 
    17 type Slab<T> = slab::Slab<T>;
    18 type Slab<T> = slab::Slab<T>;
    18 
    19 
    19 pub struct HWServer {
    20 pub struct HWServer {
    20     pub clients: Slab<HWClient>,
    21     pub clients: Slab<HWClient>,
    35             lobby_id: 0,
    36             lobby_id: 0,
    36             output: vec![],
    37             output: vec![],
    37             removed_clients: vec![],
    38             removed_clients: vec![],
    38             io,
    39             io,
    39         };
    40         };
    40         server.lobby_id = server.add_room();
    41         server.lobby_id = server.add_room().id;
    41         server
    42         server
    42     }
    43     }
    43 
    44 
    44     pub fn add_client(&mut self) -> ClientId {
    45     pub fn add_client(&mut self) -> ClientId {
    45         let key: ClientId;
    46         let key: ClientId;
    66             client_id,
    67             client_id,
    67             actions::Action::ByeClient("Connection reset".to_string()),
    68             actions::Action::ByeClient("Connection reset".to_string()),
    68         );
    69         );
    69     }
    70     }
    70 
    71 
    71     pub fn add_room(&mut self) -> RoomId {
    72     pub fn add_room(&mut self) -> &mut HWRoom {
    72         let entry = self.rooms.vacant_entry();
    73         allocate_room(&mut self.rooms)
    73         let key = entry.key();
       
    74         let room = HWRoom::new(entry.key());
       
    75         entry.insert(room);
       
    76         key
       
    77     }
    74     }
    78 
    75 
    79     pub fn handle_msg(&mut self, client_id: ClientId, msg: HWProtocolMessage) {
    76     pub fn handle_msg(&mut self, client_id: ClientId, msg: HWProtocolMessage) {
    80         debug!("Handling message {:?} for client {}", msg, client_id);
    77         debug!("Handling message {:?} for client {}", msg, client_id);
    81         if self.clients.contains(client_id) {
    78         if self.clients.contains(client_id) {
    82             handlers::handle(self, client_id, msg);
    79             handlers::handle(self, client_id, msg);
    83         }
    80         }
       
    81     }
       
    82 
       
    83     #[inline]
       
    84     pub fn create_room(
       
    85         &mut self,
       
    86         creator_id: ClientId,
       
    87         name: String,
       
    88         password: Option<String>,
       
    89     ) -> RoomId {
       
    90         create_room(
       
    91             &mut self.clients[creator_id],
       
    92             &mut self.rooms,
       
    93             name,
       
    94             password,
       
    95         )
    84     }
    96     }
    85 
    97 
    86     fn get_recipients(&self, client_id: ClientId, destination: &Destination) -> Vec<ClientId> {
    98     fn get_recipients(&self, client_id: ClientId, destination: &Destination) -> Vec<ClientId> {
    87         let mut ids = match *destination {
    99         let mut ids = match *destination {
    88             Destination::ToSelf => vec![client_id],
   100             Destination::ToSelf => vec![client_id],
   186 
   198 
   187     pub fn room(&mut self, client_id: ClientId) -> Option<&mut HWRoom> {
   199     pub fn room(&mut self, client_id: ClientId) -> Option<&mut HWRoom> {
   188         self.client_and_room(client_id).1
   200         self.client_and_room(client_id).1
   189     }
   201     }
   190 }
   202 }
       
   203 
       
   204 fn allocate_room(rooms: &mut Slab<HWRoom>) -> &mut HWRoom {
       
   205     let entry = rooms.vacant_entry();
       
   206     let key = entry.key();
       
   207     let room = HWRoom::new(entry.key());
       
   208     entry.insert(room)
       
   209 }
       
   210 
       
   211 fn create_room(
       
   212     client: &mut HWClient,
       
   213     rooms: &mut Slab<HWRoom>,
       
   214     name: String,
       
   215     password: Option<String>,
       
   216 ) -> RoomId {
       
   217     let room = allocate_room(rooms);
       
   218 
       
   219     room.master_id = Some(client.id);
       
   220     room.name = name;
       
   221     room.password = password;
       
   222     room.protocol_number = client.protocol_number;
       
   223 
       
   224     room.players_number = 1;
       
   225     room.ready_players_number = 1;
       
   226 
       
   227     client.room_id = Some(room.id);
       
   228     client.set_is_master(true);
       
   229     client.set_is_ready(true);
       
   230     client.set_is_joined_mid_game(false);
       
   231 
       
   232     room.id
       
   233 }
       
   234 
       
   235 fn move_to_room(client: &mut HWClient, room: &mut HWRoom) {
       
   236     debug_assert!(client.room_id != Some(room.id));
       
   237 
       
   238     room.players_number += 1;
       
   239 
       
   240     client.room_id = Some(room.id);
       
   241     client.set_is_joined_mid_game(room.game_info.is_some());
       
   242     client.set_is_in_game(room.game_info.is_some());
       
   243 
       
   244     if let Some(ref mut info) = room.game_info {
       
   245         let teams = info.client_teams(client.id);
       
   246         client.teams_in_game = teams.clone().count() as u8;
       
   247         client.clan = teams.clone().next().map(|t| t.color);
       
   248         let team_names: Vec<_> = teams.map(|t| t.name.clone()).collect();
       
   249 
       
   250         if !team_names.is_empty() {
       
   251             info.left_teams.retain(|name| !team_names.contains(&name));
       
   252             info.teams_in_game += team_names.len() as u8;
       
   253             room.teams = info
       
   254                 .teams_at_start
       
   255                 .iter()
       
   256                 .filter(|(_, t)| !team_names.contains(&t.name))
       
   257                 .cloned()
       
   258                 .collect();
       
   259         }
       
   260     }
       
   261 }