diff -r fbcee515b946 -r 16d3c9acd715 rust/hedgewars-server/src/core/server.rs --- a/rust/hedgewars-server/src/core/server.rs Tue Dec 24 12:46:23 2019 -0500 +++ b/rust/hedgewars-server/src/core/server.rs Tue Dec 24 20:57:58 2019 +0300 @@ -3,7 +3,7 @@ client::HwClient, indexslab::IndexSlab, room::HwRoom, - types::{ClientId, GameCfg, RoomId, ServerVar, TeamInfo}, + types::{ClientId, GameCfg, RoomId, ServerVar, TeamInfo, Vote, VoteType, Voting}, }; use crate::{protocol::messages::HwProtocolMessage::Greeting, utils}; @@ -101,6 +101,24 @@ } #[derive(Debug)] +pub enum StartVoteError { + VotingInProgress, +} + +#[derive(Debug)] +pub enum VoteResult { + Submitted, + Succeeded(VoteType), + Failed, +} + +#[derive(Debug)] +pub enum VoteError { + NoVoting, + AlreadyVoted, +} + +#[derive(Debug)] pub enum StartGameError { NotEnoughClans, NotEnoughTeams, @@ -167,11 +185,6 @@ } #[inline] - fn client_mut(&mut self, client_id: ClientId) -> &mut HwClient { - &mut self.clients[client_id] - } - - #[inline] pub fn has_client(&self, client_id: ClientId) -> bool { self.clients.contains(client_id) } @@ -187,11 +200,6 @@ } #[inline] - pub fn room_mut(&mut self, room_id: RoomId) -> &mut HwRoom { - &mut self.rooms[room_id] - } - - #[inline] pub fn get_room(&self, room_id: RoomId) -> Option<&HwRoom> { self.rooms.get(room_id) } @@ -538,6 +546,11 @@ ) } + pub fn change_client<'b: 'a>(self, client_id: ClientId) -> Option> { + let room_id = self.room_id; + HwRoomControl::new(self.server, client_id).filter(|c| c.room_id == room_id) + } + pub fn leave_room(&mut self) -> LeaveRoomResult { let (client, room) = self.get_mut(); room.players_number -= 1; @@ -586,7 +599,6 @@ new_master.set_is_master(true); if protocol_number < 42 { - todo!(); let nick = new_master.nick.clone(); self.room_mut().name = nick; } @@ -655,8 +667,44 @@ } } - pub fn vote(&mut self) { - todo!("port from the room handler") + pub fn start_vote(&mut self, kind: VoteType) -> Result<(), StartVoteError> { + use StartVoteError::*; + match self.room().voting { + Some(_) => Err(VotingInProgress), + None => { + let voting = Voting::new(kind, self.server.room_clients(self.room_id).collect()); + self.room_mut().voting = Some(voting); + Ok(()) + } + } + } + + pub fn vote(&mut self, vote: Vote) -> Result { + use self::{VoteError::*, VoteResult::*}; + let client_id = self.client_id; + if let Some(ref mut voting) = self.room_mut().voting { + if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) { + voting.votes.push((client_id, vote.is_pro)); + let i = voting.votes.iter(); + let pro = i.clone().filter(|(_, v)| *v).count(); + let contra = i.filter(|(_, v)| !*v).count(); + let success_quota = voting.voters.len() / 2 + 1; + if vote.is_forced && vote.is_pro || pro >= success_quota { + let voting = self.room_mut().voting.take().unwrap(); + Ok(Succeeded(voting.kind)) + } else if vote.is_forced && !vote.is_pro + || contra > voting.voters.len() - success_quota + { + Ok(Failed) + } else { + Ok(Submitted) + } + } else { + Err(AlreadyVoted) + } + } else { + Err(NoVoting) + } } pub fn add_engine_message(&mut self) { @@ -759,6 +807,10 @@ } } + pub fn set_hedgehogs_number(&mut self, number: u8) -> Vec { + self.room_mut().set_hedgehogs_number(number) + } + pub fn add_team(&mut self, mut info: Box) -> Result<&TeamInfo, AddTeamError> { use AddTeamError::*; let (client, room) = self.get_mut(); @@ -841,6 +893,10 @@ self.room_mut().save_config(name, location); } + pub fn load_config(&mut self, name: &str) -> Option<&str> { + self.room_mut().load_config(name) + } + pub fn delete_config(&mut self, name: &str) -> bool { self.room_mut().delete_config(name) } @@ -885,6 +941,13 @@ } } + pub fn toggle_pause(&mut self) -> bool { + if let Some(ref mut info) = self.room_mut().game_info { + info.is_paused = !info.is_paused; + } + self.room_mut().game_info.is_some() + } + pub fn leave_game(&mut self) -> Option> { let (client, room) = self.get_mut(); let client_left = client.is_in_game();