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 { |
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(); |
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 { |