rust/hedgewars-server/src/core/server.rs
changeset 15986 cd8392e52165
parent 15938 ce47259d5c86
child 15988 0b2e0a7d0431
equal deleted inserted replaced
15985:e42d1819b150 15986:cd8392e52165
    10 
    10 
    11 use crate::server::replaystorage::ReplayStorage;
    11 use crate::server::replaystorage::ReplayStorage;
    12 
    12 
    13 use bitflags::*;
    13 use bitflags::*;
    14 use log::*;
    14 use log::*;
       
    15 use rand::{self, seq::SliceRandom, thread_rng, Rng};
    15 use slab::Slab;
    16 use slab::Slab;
    16 use std::{borrow::BorrowMut, cmp::min, collections::HashSet, iter, mem::replace};
    17 use std::{borrow::BorrowMut, cmp::min, collections::HashSet, iter, mem::replace};
    17 
    18 
    18 #[derive(Debug)]
    19 #[derive(Debug)]
    19 pub enum CreateRoomError {
    20 pub enum CreateRoomError {
   107 pub enum StartVoteError {
   108 pub enum StartVoteError {
   108     VotingInProgress,
   109     VotingInProgress,
   109 }
   110 }
   110 
   111 
   111 #[derive(Debug)]
   112 #[derive(Debug)]
       
   113 pub enum VoteEffect {
       
   114     Kicked(ClientId, LeaveRoomResult),
       
   115     Map(String),
       
   116     Pause,
       
   117     NewSeed(GameCfg),
       
   118     HedgehogsPerTeam(u8, Vec<String>),
       
   119 }
       
   120 
       
   121 #[derive(Debug)]
   112 pub enum VoteResult {
   122 pub enum VoteResult {
   113     Submitted,
   123     Submitted,
   114     Succeeded(VoteType),
   124     Succeeded(VoteEffect),
   115     Failed,
   125     Failed,
   116 }
   126 }
   117 
   127 
   118 #[derive(Debug)]
   128 #[derive(Debug)]
   119 pub enum VoteError {
   129 pub enum VoteError {
   607     pub fn change_client<'b: 'a>(self, client_id: ClientId) -> Option<HwRoomControl<'a>> {
   617     pub fn change_client<'b: 'a>(self, client_id: ClientId) -> Option<HwRoomControl<'a>> {
   608         let room_id = self.room_id;
   618         let room_id = self.room_id;
   609         HwRoomControl::new(self.server, client_id).filter(|c| c.room_id == room_id)
   619         HwRoomControl::new(self.server, client_id).filter(|c| c.room_id == room_id)
   610     }
   620     }
   611 
   621 
   612     pub fn leave_room(&mut self) -> LeaveRoomResult {
   622     fn remove_from_room(&mut self, client_id: ClientId) -> LeaveRoomResult {
   613         let (client, room) = self.get_mut();
   623         let Some((client, room)) = self.server.client_and_room_mut(client_id);
   614         room.players_number -= 1;
   624         room.players_number -= 1;
   615         client.room_id = None;
   625         client.room_id = None;
   616 
   626 
   617         let is_empty = room.players_number == 0;
   627         let is_empty = room.players_number == 0;
   618         let is_fixed = room.is_fixed();
   628         let is_fixed = room.is_fixed();
   687                 removed_teams,
   697                 removed_teams,
   688             }
   698             }
   689         }
   699         }
   690     }
   700     }
   691 
   701 
       
   702     pub fn leave_room(&mut self) -> LeaveRoomResult {
       
   703         self.remove_from_room(self.client_id)
       
   704     }
       
   705 
   692     pub fn change_master(
   706     pub fn change_master(
   693         &mut self,
   707         &mut self,
   694         new_master_nick: String,
   708         new_master_nick: String,
   695     ) -> Result<ChangeMasterResult, ChangeMasterError> {
   709     ) -> Result<ChangeMasterResult, ChangeMasterError> {
   696         use ChangeMasterError::*;
   710         use ChangeMasterError::*;
   741                 Ok(())
   755                 Ok(())
   742             }
   756             }
   743         }
   757         }
   744     }
   758     }
   745 
   759 
       
   760     fn apply_vote(&mut self, kind: VoteType) -> Option<VoteEffect> {
       
   761         match kind {
       
   762             VoteType::Kick(nick) => {
       
   763                 if let Some(kicked_id) = self
       
   764                     .server
       
   765                     .find_client(&nick)
       
   766                     .filter(|c| c.room_id == Some(self.room_id))
       
   767                     .map(|c| c.id)
       
   768                 {
       
   769                     let leave_result = self.remove_from_room(kicked_id);
       
   770                     Some(VoteEffect::Kicked(kicked_id, leave_result))
       
   771                 } else {
       
   772                     None
       
   773                 }
       
   774             }
       
   775             VoteType::Map(None) => None,
       
   776             VoteType::Map(Some(name)) => self
       
   777                 .load_config(&name)
       
   778                 .map(|s| VoteEffect::Map(s.to_string())),
       
   779             VoteType::Pause => Some(VoteEffect::Pause).filter(|_| self.toggle_pause()),
       
   780             VoteType::NewSeed => {
       
   781                 let seed = thread_rng().gen_range(0..1_000_000_000).to_string();
       
   782                 let cfg = GameCfg::Seed(seed);
       
   783                 todo!("Protocol backwards compatibility");
       
   784                 self.room_mut().set_config(cfg.clone());
       
   785                 Some(VoteEffect::NewSeed(cfg))
       
   786             }
       
   787             VoteType::HedgehogsPerTeam(number) => {
       
   788                 let nicks = self.set_hedgehogs_number(number);
       
   789                 Some(VoteEffect::HedgehogsPerTeam(number, nicks))
       
   790             }
       
   791         }
       
   792     }
       
   793 
   746     pub fn vote(&mut self, vote: Vote) -> Result<VoteResult, VoteError> {
   794     pub fn vote(&mut self, vote: Vote) -> Result<VoteResult, VoteError> {
   747         use self::{VoteError::*, VoteResult::*};
   795         use self::{VoteError::*, VoteResult::*};
   748         let client_id = self.client_id;
   796         let client_id = self.client_id;
   749         if let Some(ref mut voting) = self.room_mut().voting {
   797         if let Some(ref mut voting) = self.room_mut().voting {
   750             if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) {
   798             if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) {
   751                 voting.votes.push((client_id, vote.is_pro));
   799                 voting.votes.push((client_id, vote.is_pro));
   752                 let i = voting.votes.iter();
   800                 let i = voting.votes.iter();
   753                 let pro = i.clone().filter(|(_, v)| *v).count();
   801                 let pro = i.clone().filter(|(_, v)| *v).count();
   754                 let contra = i.filter(|(_, v)| !*v).count();
   802                 let contra = i.filter(|(_, v)| !*v).count();
   755                 let success_quota = voting.voters.len() / 2 + 1;
   803                 let success_quota = voting.voters.len() / 2 + 1;
       
   804                 
   756                 if vote.is_forced && vote.is_pro || pro >= success_quota {
   805                 if vote.is_forced && vote.is_pro || pro >= success_quota {
   757                     let voting = self.room_mut().voting.take().unwrap();
   806                     let voting = self.room_mut().voting.take().unwrap();
   758                     Ok(Succeeded(voting.kind))
   807                     if let Some(effect) = self.apply_vote(voting.kind) {
       
   808                         Ok(Succeeded(effect))
       
   809                     } else {
       
   810                         Ok(Failed)
       
   811                     }
   759                 } else if vote.is_forced && !vote.is_pro
   812                 } else if vote.is_forced && !vote.is_pro
   760                     || contra > voting.voters.len() - success_quota
   813                     || contra > voting.voters.len() - success_quota
   761                 {
   814                 {
   762                     Ok(Failed)
   815                     Ok(Failed)
   763                 } else {
   816                 } else {
   939                     }
   992                     }
   940                     GameCfg::Scheme(name, values)
   993                     GameCfg::Scheme(name, values)
   941                 }
   994                 }
   942                 cfg => cfg,
   995                 cfg => cfg,
   943             };
   996             };
   944 
       
   945             room.set_config(cfg);
   997             room.set_config(cfg);
   946             Ok(())
   998             Ok(())
   947         }
   999         }
   948     }
  1000     }
   949 
  1001