rust/hedgewars-server/src/handlers/common.rs
changeset 15075 e935b1ad23f3
parent 15074 c5a6e8566425
child 15111 1e45db229f9f
equal deleted inserted replaced
15074:c5a6e8566425 15075:e935b1ad23f3
     1 use crate::{
     1 use crate::{
       
     2     core::{
       
     3         client::HwClient,
       
     4         room::HwRoom,
       
     5         server::HwServer,
       
     6         types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType},
       
     7     },
     2     protocol::messages::{
     8     protocol::messages::{
     3         server_chat,
     9         add_flags, remove_flags, server_chat,
     4         add_flags, remove_flags,
    10         HwProtocolMessage::{self, Rnd},
     5         HWProtocolMessage::{self, Rnd},
    11         HwServerMessage::{self, *},
     6         HWServerMessage::{self, *},
       
     7         ProtocolFlags as Flags,
    12         ProtocolFlags as Flags,
     8     },
       
     9     core::{
       
    10         client::HWClient,
       
    11         server::HWServer,
       
    12         types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType},
       
    13         room::HWRoom,
       
    14     },
    13     },
    15     utils::to_engine_msg,
    14     utils::to_engine_msg,
    16 };
    15 };
    17 
    16 
    18 use super::Response;
    17 use super::Response;
    19 
    18 
    20 use crate::core::types::RoomConfig;
    19 use crate::core::types::RoomConfig;
    21 use rand::{self, seq::SliceRandom, thread_rng, Rng};
    20 use rand::{self, seq::SliceRandom, thread_rng, Rng};
    22 use std::{iter::once, mem::replace};
    21 use std::{iter::once, mem::replace};
    23 
    22 
    24 pub fn rnd_reply(options: &[String]) -> HWServerMessage {
    23 pub fn rnd_reply(options: &[String]) -> HwServerMessage {
    25     let mut rng = thread_rng();
    24     let mut rng = thread_rng();
    26 
    25 
    27     let reply = if options.is_empty() {
    26     let reply = if options.is_empty() {
    28         (*&["heads", "tails"].choose(&mut rng).unwrap()).to_string()
    27         (*&["heads", "tails"].choose(&mut rng).unwrap()).to_string()
    29     } else {
    28     } else {
    34         nick: "[random]".to_string(),
    33         nick: "[random]".to_string(),
    35         msg: reply,
    34         msg: reply,
    36     }
    35     }
    37 }
    36 }
    38 
    37 
    39 pub fn join_lobby(server: &mut HWServer, response: &mut Response) {
    38 pub fn join_lobby(server: &mut HwServer, response: &mut Response) {
    40     let client_id = response.client_id();
    39     let client_id = response.client_id();
    41 
    40 
    42     let client = &server.clients[client_id];
    41     let client = &server.clients[client_id];
    43     let nick = vec![client.nick.clone()];
    42     let nick = vec![client.nick.clone()];
    44     let mut flags = vec![];
    43     let mut flags = vec![];
    98     response.add(server_msg.send_self());
    97     response.add(server_msg.send_self());
    99     response.add(rooms_msg.send_self());
    98     response.add(rooms_msg.send_self());
   100 }
    99 }
   101 
   100 
   102 pub fn remove_teams(
   101 pub fn remove_teams(
   103     room: &mut HWRoom,
   102     room: &mut HwRoom,
   104     team_names: Vec<String>,
   103     team_names: Vec<String>,
   105     is_in_game: bool,
   104     is_in_game: bool,
   106     response: &mut Response,
   105     response: &mut Response,
   107 ) {
   106 ) {
   108     if let Some(ref mut info) = room.game_info {
   107     if let Some(ref mut info) = room.game_info {
   142         response.add(TeamRemove(team_name).send_all().in_room(room.id));
   141         response.add(TeamRemove(team_name).send_all().in_room(room.id));
   143     }
   142     }
   144 }
   143 }
   145 
   144 
   146 fn remove_client_from_room(
   145 fn remove_client_from_room(
   147     client: &mut HWClient,
   146     client: &mut HwClient,
   148     room: &mut HWRoom,
   147     room: &mut HwRoom,
   149     response: &mut Response,
   148     response: &mut Response,
   150     msg: &str,
   149     msg: &str,
   151 ) {
   150 ) {
   152     room.players_number -= 1;
   151     room.players_number -= 1;
   153     if room.players_number > 0 || room.is_fixed() {
   152     if room.players_number > 0 || room.is_fixed() {
   195 
   194 
   196     response.add(ClientFlags(remove_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_all());
   195     response.add(ClientFlags(remove_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_all());
   197 }
   196 }
   198 
   197 
   199 pub fn change_master(
   198 pub fn change_master(
   200     server: &mut HWServer,
   199     server: &mut HwServer,
   201     room_id: RoomId,
   200     room_id: RoomId,
   202     new_master_id: ClientId,
   201     new_master_id: ClientId,
   203     response: &mut Response,
   202     response: &mut Response,
   204 ) {
   203 ) {
   205     let room = &mut server.rooms[room_id];
   204     let room = &mut server.rooms[room_id];
   227         .in_room(room_id),
   226         .in_room(room_id),
   228     );
   227     );
   229 }
   228 }
   230 
   229 
   231 pub fn enter_room(
   230 pub fn enter_room(
   232     server: &mut HWServer,
   231     server: &mut HwServer,
   233     client_id: ClientId,
   232     client_id: ClientId,
   234     room_id: RoomId,
   233     room_id: RoomId,
   235     response: &mut Response,
   234     response: &mut Response,
   236 ) {
   235 ) {
   237     let nick = server.clients[client_id].nick.clone();
   236     let nick = server.clients[client_id].nick.clone();
   269             .send_self(),
   268             .send_self(),
   270         );
   269         );
   271     }
   270     }
   272 }
   271 }
   273 
   272 
   274 pub fn exit_room(server: &mut HWServer, client_id: ClientId, response: &mut Response, msg: &str) {
   273 pub fn exit_room(server: &mut HwServer, client_id: ClientId, response: &mut Response, msg: &str) {
   275     let client = &mut server.clients[client_id];
   274     let client = &mut server.clients[client_id];
   276 
   275 
   277     if let Some(room_id) = client.room_id {
   276     if let Some(room_id) = client.room_id {
   278         let room = &mut server.rooms[room_id];
   277         let room = &mut server.rooms[room_id];
   279 
   278 
   307             }
   306             }
   308         }
   307         }
   309     }
   308     }
   310 }
   309 }
   311 
   310 
   312 pub fn remove_client(server: &mut HWServer, response: &mut Response, msg: String) {
   311 pub fn remove_client(server: &mut HwServer, response: &mut Response, msg: String) {
   313     let client_id = response.client_id();
   312     let client_id = response.client_id();
   314     let client = &mut server.clients[client_id];
   313     let client = &mut server.clients[client_id];
   315     let nick = client.nick.clone();
   314     let nick = client.nick.clone();
   316 
   315 
   317     exit_room(server, client_id, response, &msg);
   316     exit_room(server, client_id, response, &msg);
   323     response.remove_client(client_id);
   322     response.remove_client(client_id);
   324 }
   323 }
   325 
   324 
   326 pub fn get_room_update(
   325 pub fn get_room_update(
   327     room_name: Option<String>,
   326     room_name: Option<String>,
   328     room: &HWRoom,
   327     room: &HwRoom,
   329     master: Option<&HWClient>,
   328     master: Option<&HwClient>,
   330     response: &mut Response,
   329     response: &mut Response,
   331 ) {
   330 ) {
   332     let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master));
   331     let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master));
   333     response.add(update_msg.send_all().with_protocol(room.protocol_number));
   332     response.add(update_msg.send_all().with_protocol(room.protocol_number));
   334 }
   333 }
   338     for cfg in config.to_game_config() {
   337     for cfg in config.to_game_config() {
   339         response.add(cfg.to_server_msg().send(to_client));
   338         response.add(cfg.to_server_msg().send(to_client));
   340     }
   339     }
   341 }
   340 }
   342 
   341 
   343 pub fn get_room_config(room: &HWRoom, to_client: ClientId, response: &mut Response) {
   342 pub fn get_room_config(room: &HwRoom, to_client: ClientId, response: &mut Response) {
   344     get_room_config_impl(room.active_config(), to_client, response);
   343     get_room_config_impl(room.active_config(), to_client, response);
   345 }
   344 }
   346 
   345 
   347 pub fn get_teams<'a, I>(teams: I, to_client: ClientId, response: &mut Response)
   346 pub fn get_teams<'a, I>(teams: I, to_client: ClientId, response: &mut Response)
   348 where
   347 where
   354         response.add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send(to_client));
   353         response.add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send(to_client));
   355     }
   354     }
   356 }
   355 }
   357 
   356 
   358 pub fn get_room_teams(
   357 pub fn get_room_teams(
   359     server: &HWServer,
   358     server: &HwServer,
   360     room_id: RoomId,
   359     room_id: RoomId,
   361     to_client: ClientId,
   360     to_client: ClientId,
   362     response: &mut Response,
   361     response: &mut Response,
   363 ) {
   362 ) {
   364     let room = &server.rooms[room_id];
   363     let room = &server.rooms[room_id];
   369 
   368 
   370     get_teams(current_teams.iter().map(|(_, t)| t), to_client, response);
   369     get_teams(current_teams.iter().map(|(_, t)| t), to_client, response);
   371 }
   370 }
   372 
   371 
   373 pub fn get_room_flags(
   372 pub fn get_room_flags(
   374     server: &HWServer,
   373     server: &HwServer,
   375     room_id: RoomId,
   374     room_id: RoomId,
   376     to_client: ClientId,
   375     to_client: ClientId,
   377     response: &mut Response,
   376     response: &mut Response,
   378 ) {
   377 ) {
   379     let room = &server.rooms[room_id];
   378     let room = &server.rooms[room_id];
   396         response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client));
   395         response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client));
   397     }
   396     }
   398 }
   397 }
   399 
   398 
   400 pub fn apply_voting_result(
   399 pub fn apply_voting_result(
   401     server: &mut HWServer,
   400     server: &mut HwServer,
   402     room_id: RoomId,
   401     room_id: RoomId,
   403     response: &mut Response,
   402     response: &mut Response,
   404     kind: VoteType,
   403     kind: VoteType,
   405 ) {
   404 ) {
   406     match kind {
   405     match kind {
   468             );
   467             );
   469         }
   468         }
   470     }
   469     }
   471 }
   470 }
   472 
   471 
   473 fn add_vote(room: &mut HWRoom, response: &mut Response, vote: Vote) -> Option<bool> {
   472 fn add_vote(room: &mut HwRoom, response: &mut Response, vote: Vote) -> Option<bool> {
   474     let client_id = response.client_id;
   473     let client_id = response.client_id;
   475     let mut result = None;
   474     let mut result = None;
   476 
   475 
   477     if let Some(ref mut voting) = room.voting {
   476     if let Some(ref mut voting) = room.voting {
   478         if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) {
   477         if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) {
   496     }
   495     }
   497 
   496 
   498     result
   497     result
   499 }
   498 }
   500 
   499 
   501 pub fn submit_vote(server: &mut HWServer, vote: Vote, response: &mut Response) {
   500 pub fn submit_vote(server: &mut HwServer, vote: Vote, response: &mut Response) {
   502     let client_id = response.client_id;
   501     let client_id = response.client_id;
   503     let client = &server.clients[client_id];
   502     let client = &server.clients[client_id];
   504 
   503 
   505     if let Some(room_id) = client.room_id {
   504     if let Some(room_id) = client.room_id {
   506         let room = &mut server.rooms[room_id];
   505         let room = &mut server.rooms[room_id];
   517             }
   516             }
   518         }
   517         }
   519     }
   518     }
   520 }
   519 }
   521 
   520 
   522 pub fn start_game(server: &mut HWServer, room_id: RoomId, response: &mut Response) {
   521 pub fn start_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) {
   523     let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server
   522     let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server
   524         .clients
   523         .clients
   525         .iter()
   524         .iter()
   526         .map(|(id, c)| (id, c.nick.clone()))
   525         .map(|(id, c)| (id, c.nick.clone()))
   527         .unzip();
   526         .unzip();
   556         };
   555         };
   557         get_room_update(None, room, room_master, response);
   556         get_room_update(None, room, room_master, response);
   558     }
   557     }
   559 }
   558 }
   560 
   559 
   561 pub fn end_game(server: &mut HWServer, room_id: RoomId, response: &mut Response) {
   560 pub fn end_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) {
   562     let room = &mut server.rooms[room_id];
   561     let room = &mut server.rooms[room_id];
   563     room.ready_players_number = 1;
   562     room.ready_players_number = 1;
   564     let room_master = if let Some(id) = room.master_id {
   563     let room_master = if let Some(id) = room.master_id {
   565         Some(&server.clients[id])
   564         Some(&server.clients[id])
   566     } else {
   565     } else {
   611 }
   610 }
   612 
   611 
   613 #[cfg(test)]
   612 #[cfg(test)]
   614 mod tests {
   613 mod tests {
   615     use super::*;
   614     use super::*;
   616     use crate::protocol::messages::HWServerMessage::ChatMsg;
   615     use crate::protocol::messages::HwServerMessage::ChatMsg;
   617     use crate::server::actions::PendingMessage;
   616     use crate::server::actions::PendingMessage;
   618 
   617 
   619     fn reply2string(r: HWServerMessage) -> String {
   618     fn reply2string(r: HwServerMessage) -> String {
   620         match r {
   619         match r {
   621             ChatMsg { msg: p, .. } => String::from(p),
   620             ChatMsg { msg: p, .. } => String::from(p),
   622             _ => panic!("expected a ChatMsg"),
   621             _ => panic!("expected a ChatMsg"),
   623         }
   622         }
   624     }
   623     }