rust/hedgewars-server/src/server/handlers/common.rs
changeset 14687 5122c584804e
parent 14686 9f98086de1b6
child 14688 4569d8d50286
equal deleted inserted replaced
14686:9f98086de1b6 14687:5122c584804e
     1 use crate::protocol::messages::server_chat;
     1 use crate::protocol::messages::server_chat;
     2 use crate::server::client::HWClient;
     2 use crate::server::client::HWClient;
     3 use crate::server::coretypes::ClientId;
     3 use crate::server::coretypes::ClientId;
       
     4 use crate::server::coretypes::GameCfg;
       
     5 use crate::server::coretypes::RoomId;
       
     6 use crate::server::coretypes::Vote;
       
     7 use crate::server::coretypes::VoteType;
     4 use crate::server::room::HWRoom;
     8 use crate::server::room::HWRoom;
     5 use crate::utils::to_engine_msg;
     9 use crate::utils::to_engine_msg;
     6 use crate::{
    10 use crate::{
     7     protocol::messages::{
    11     protocol::messages::{
     8         HWProtocolMessage::{self, Rnd},
    12         HWProtocolMessage::{self, Rnd},
     9         HWServerMessage::{
    13         HWServerMessage::{
    10             self, Bye, ChatMsg, ClientFlags, ForwardEngineMessage, LobbyJoined, LobbyLeft, Notice,
    14             self, Bye, ChatMsg, ClientFlags, ForwardEngineMessage, HedgehogsNumber, Kicked,
    11             RoomLeft, RoomRemove, RoomUpdated, Rooms, ServerMessage, TeamRemove,
    15             LobbyJoined, LobbyLeft, Notice, RoomLeft, RoomRemove, RoomUpdated, Rooms,
       
    16             ServerMessage, TeamRemove,
    12         },
    17         },
    13     },
    18     },
    14     server::{actions::Action, core::HWServer},
    19     server::{actions::Action, core::HWServer},
    15 };
    20 };
    16 use rand::{self, thread_rng, Rng};
    21 use rand::{self, thread_rng, Rng};
   189 }
   194 }
   190 
   195 
   191 pub fn get_room_update(
   196 pub fn get_room_update(
   192     room_name: Option<String>,
   197     room_name: Option<String>,
   193     room: &HWRoom,
   198     room: &HWRoom,
   194     client: Option<&HWClient>,
   199     master: Option<&HWClient>,
   195     response: &mut super::Response,
   200     response: &mut super::Response,
   196 ) {
   201 ) {
   197     let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(client));
   202     let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master));
   198     response.add(update_msg.send_all().with_protocol(room.protocol_number));
   203     response.add(update_msg.send_all().with_protocol(room.protocol_number));
   199 }
   204 }
   200 
   205 
   201 pub fn add_vote(room: &mut HWRoom, response: &mut super::Response, vote: bool, is_forced: bool) {
   206 pub fn apply_voting_result(
       
   207     server: &mut HWServer,
       
   208     room_id: RoomId,
       
   209     response: &mut super::Response,
       
   210     kind: VoteType,
       
   211 ) {
       
   212     let client_id = response.client_id;
       
   213 
       
   214     match kind {
       
   215         VoteType::Kick(nick) => {
       
   216             if let Some(client) = server.find_client(&nick) {
       
   217                 if client.room_id == Some(room_id) {
       
   218                     let id = client.id;
       
   219                     response.add(Kicked.send_self());
       
   220                     exit_room(
       
   221                         &mut server.clients[client_id],
       
   222                         &mut server.rooms[room_id],
       
   223                         response,
       
   224                         "kicked",
       
   225                     );
       
   226                 }
       
   227             }
       
   228         }
       
   229         VoteType::Map(None) => (),
       
   230         VoteType::Map(Some(name)) => {
       
   231             if let Some(location) = server.rooms[room_id].load_config(&name) {
       
   232                 response.add(
       
   233                     server_chat(location.to_string())
       
   234                         .send_all()
       
   235                         .in_room(room_id),
       
   236                 );
       
   237                 get_room_update(
       
   238                     None,
       
   239                     &server.rooms[room_id],
       
   240                     Some(&server.clients[client_id]),
       
   241                     response,
       
   242                 );
       
   243 
       
   244                 for (_, c) in server.clients.iter() {
       
   245                     if c.room_id == Some(room_id) {
       
   246                         /*SendRoomData {
       
   247                             to: c.id,
       
   248                             teams: false,
       
   249                             config: true,
       
   250                             flags: false,
       
   251                         }*/
       
   252                     }
       
   253                 }
       
   254             }
       
   255         }
       
   256         VoteType::Pause => {
       
   257             if let Some(ref mut info) = server.rooms[room_id].game_info {
       
   258                 info.is_paused = !info.is_paused;
       
   259                 response.add(
       
   260                     server_chat("Pause toggled.".to_string())
       
   261                         .send_all()
       
   262                         .in_room(room_id),
       
   263                 );
       
   264                 response.add(
       
   265                     ForwardEngineMessage(vec![to_engine_msg(once(b'I'))])
       
   266                         .send_all()
       
   267                         .in_room(room_id),
       
   268                 );
       
   269             }
       
   270         }
       
   271         VoteType::NewSeed => {
       
   272             let seed = thread_rng().gen_range(0, 1_000_000_000).to_string();
       
   273             let cfg = GameCfg::Seed(seed);
       
   274             response.add(cfg.to_server_msg().send_all().in_room(room_id));
       
   275             server.rooms[room_id].set_config(cfg);
       
   276         }
       
   277         VoteType::HedgehogsPerTeam(number) => {
       
   278             let r = &mut server.rooms[room_id];
       
   279             let nicks = r.set_hedgehogs_number(number);
       
   280 
       
   281             response.extend(
       
   282                 nicks
       
   283                     .into_iter()
       
   284                     .map(|n| HedgehogsNumber(n, number).send_all().in_room(room_id)),
       
   285             );
       
   286         }
       
   287     }
       
   288 }
       
   289 
       
   290 fn add_vote(room: &mut HWRoom, response: &mut super::Response, vote: Vote) -> Option<bool> {
   202     let client_id = response.client_id;
   291     let client_id = response.client_id;
   203     let mut result = None;
   292     let mut result = None;
       
   293 
   204     if let Some(ref mut voting) = room.voting {
   294     if let Some(ref mut voting) = room.voting {
   205         if is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) {
   295         if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) {
   206             response.add(server_chat("Your vote has been counted.".to_string()).send_self());
   296             response.add(server_chat("Your vote has been counted.".to_string()).send_self());
   207             voting.votes.push((client_id, vote));
   297             voting.votes.push((client_id, vote.is_pro));
   208             let i = voting.votes.iter();
   298             let i = voting.votes.iter();
   209             let pro = i.clone().filter(|(_, v)| *v).count();
   299             let pro = i.clone().filter(|(_, v)| *v).count();
   210             let contra = i.filter(|(_, v)| !*v).count();
   300             let contra = i.filter(|(_, v)| !*v).count();
   211             let success_quota = voting.voters.len() / 2 + 1;
   301             let success_quota = voting.voters.len() / 2 + 1;
   212             if is_forced && vote || pro >= success_quota {
   302             if vote.is_forced && vote.is_pro || pro >= success_quota {
   213                 result = Some(true);
   303                 result = Some(true);
   214             } else if is_forced && !vote || contra > voting.voters.len() - success_quota {
   304             } else if vote.is_forced && !vote.is_pro || contra > voting.voters.len() - success_quota
       
   305             {
   215                 result = Some(false);
   306                 result = Some(false);
   216             }
   307             }
   217         } else {
   308         } else {
   218             response.add(server_chat("You already have voted.".to_string()).send_self());
   309             response.add(server_chat("You already have voted.".to_string()).send_self());
   219         }
   310         }
   220     } else {
   311     } else {
   221         response.add(server_chat("There's no voting going on.".to_string()).send_self());
   312         response.add(server_chat("There's no voting going on.".to_string()).send_self());
   222     }
   313     }
   223 
   314 
   224     if let Some(res) = result {
   315     result
   225         response.add(
   316 }
   226             server_chat("Voting closed.".to_string())
   317 
   227                 .send_all()
   318 pub fn submit_vote(server: &mut HWServer, vote: Vote, response: &mut super::Response) {
   228                 .in_room(room.id),
   319     let client_id = response.client_id;
   229         );
   320     let client = &server.clients[client_id];
   230         let voting = replace(&mut room.voting, None).unwrap();
   321 
   231         if res {
   322     if let Some(room_id) = client.room_id {
   232             //ApplyVoting(voting.kind, room.id));
   323         let room = &mut server.rooms[room_id];
       
   324 
       
   325         if let Some(res) = add_vote(room, response, vote) {
       
   326             response.add(
       
   327                 server_chat("Voting closed.".to_string())
       
   328                     .send_all()
       
   329                     .in_room(room.id),
       
   330             );
       
   331             let voting = replace(&mut room.voting, None).unwrap();
       
   332             if res {
       
   333                 apply_voting_result(server, room_id, response, voting.kind);
       
   334             }
   233         }
   335         }
   234     }
   336     }
   235 }
   337 }
   236 
   338 
   237 #[cfg(test)]
   339 #[cfg(test)]