diff -r 5122c584804e -r 4569d8d50286 rust/hedgewars-server/src/server/handlers/common.rs --- a/rust/hedgewars-server/src/server/handlers/common.rs Wed Feb 06 00:57:01 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers/common.rs Wed Feb 06 20:48:40 2019 +0300 @@ -1,26 +1,23 @@ -use crate::protocol::messages::server_chat; -use crate::server::client::HWClient; -use crate::server::coretypes::ClientId; -use crate::server::coretypes::GameCfg; -use crate::server::coretypes::RoomId; -use crate::server::coretypes::Vote; -use crate::server::coretypes::VoteType; -use crate::server::room::HWRoom; -use crate::utils::to_engine_msg; use crate::{ + protocol::messages::server_chat, protocol::messages::{ HWProtocolMessage::{self, Rnd}, - HWServerMessage::{ - self, Bye, ChatMsg, ClientFlags, ForwardEngineMessage, HedgehogsNumber, Kicked, - LobbyJoined, LobbyLeft, Notice, RoomLeft, RoomRemove, RoomUpdated, Rooms, - ServerMessage, TeamRemove, - }, + HWServerMessage::{self, *}, }, - server::{actions::Action, core::HWServer}, + server::{ + actions::Action, + client::HWClient, + core::HWServer, + coretypes::{ClientId, GameCfg, RoomId, Vote, VoteType}, + room::HWRoom, + }, + utils::to_engine_msg, }; + +use super::Response; + use rand::{self, thread_rng, Rng}; -use std::iter::once; -use std::mem::replace; +use std::{iter::once, mem::replace}; pub fn rnd_reply(options: &[String]) -> HWServerMessage { let mut rng = thread_rng(); @@ -36,7 +33,7 @@ } } -pub fn process_login(server: &mut HWServer, response: &mut super::Response) { +pub fn process_login(server: &mut HWServer, response: &mut Response) { let client_id = response.client_id(); let nick = server.clients[client_id].nick.clone(); @@ -97,7 +94,7 @@ room: &mut HWRoom, team_names: Vec, is_in_game: bool, - response: &mut super::Response, + response: &mut Response, ) { if let Some(ref mut info) = room.game_info { for team_name in &team_names { @@ -140,7 +137,7 @@ } } -pub fn exit_room(client: &HWClient, room: &mut HWRoom, response: &mut super::Response, msg: &str) { +pub fn exit_room(client: &HWClient, room: &mut HWRoom, response: &mut Response, msg: &str) { if room.players_number > 1 || room.is_fixed() { room.players_number -= 1; if client.is_ready() && room.ready_players_number > 0 { @@ -175,7 +172,7 @@ response.add(ClientFlags("-i".to_string(), vec![client.nick.clone()]).send_all()); } -pub fn remove_client(server: &mut HWServer, response: &mut super::Response, msg: String) { +pub fn remove_client(server: &mut HWServer, response: &mut Response, msg: String) { let client_id = response.client_id(); let lobby_id = server.lobby_id; let client = &mut server.clients[client_id]; @@ -197,7 +194,7 @@ room_name: Option, room: &HWRoom, master: Option<&HWClient>, - response: &mut super::Response, + response: &mut Response, ) { let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master)); response.add(update_msg.send_all().with_protocol(room.protocol_number)); @@ -206,7 +203,7 @@ pub fn apply_voting_result( server: &mut HWServer, room_id: RoomId, - response: &mut super::Response, + response: &mut Response, kind: VoteType, ) { let client_id = response.client_id; @@ -234,12 +231,13 @@ .send_all() .in_room(room_id), ); - get_room_update( - None, - &server.rooms[room_id], - Some(&server.clients[client_id]), - response, - ); + let room = &server.rooms[room_id]; + let room_master = if let Some(id) = room.master_id { + Some(&server.clients[id]) + } else { + None + }; + get_room_update(None, room, room_master, response); for (_, c) in server.clients.iter() { if c.room_id == Some(room_id) { @@ -287,7 +285,7 @@ } } -fn add_vote(room: &mut HWRoom, response: &mut super::Response, vote: Vote) -> Option { +fn add_vote(room: &mut HWRoom, response: &mut Response, vote: Vote) -> Option { let client_id = response.client_id; let mut result = None; @@ -315,7 +313,7 @@ result } -pub fn submit_vote(server: &mut HWServer, vote: Vote, response: &mut super::Response) { +pub fn submit_vote(server: &mut HWServer, vote: Vote, response: &mut Response) { let client_id = response.client_id; let client = &server.clients[client_id]; @@ -336,6 +334,98 @@ } } +pub fn start_game(server: &mut HWServer, room_id: RoomId, response: &mut Response) { + let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server + .clients + .iter() + .map(|(id, c)| (id, c.nick.clone())) + .unzip(); + let room = &mut server.rooms[room_id]; + + if !room.has_multiple_clans() { + response.add( + Warning("The game can't be started with less than two clans!".to_string()).send_self(), + ); + } else if room.protocol_number <= 43 && room.players_number != room.ready_players_number { + response.add(Warning("Not all players are ready".to_string()).send_self()); + } else if room.game_info.is_some() { + response.add(Warning("The game is already in progress".to_string()).send_self()); + } else { + room.start_round(); + for id in room_clients { + let c = &mut server.clients[id]; + c.set_is_in_game(false); + c.team_indices = room.client_team_indices(c.id); + } + response.add(RunGame.send_all().in_room(room.id)); + response.add( + ClientFlags("+g".to_string(), room_nicks) + .send_all() + .in_room(room.id), + ); + + let room_master = if let Some(id) = room.master_id { + Some(&server.clients[id]) + } else { + None + }; + get_room_update(None, room, room_master, response); + } +} + +pub fn end_game(server: &mut HWServer, room_id: RoomId, response: &mut Response) { + let room = &mut server.rooms[room_id]; + room.ready_players_number = 1; + let room_master = if let Some(id) = room.master_id { + Some(&server.clients[id]) + } else { + None + }; + get_room_update(None, room, room_master, response); + response.add(RoundFinished.send_all().in_room(room_id)); + + if let Some(info) = replace(&mut room.game_info, None) { + for (_, client) in server.clients.iter() { + if client.room_id == Some(room_id) && client.is_joined_mid_game() { + //SendRoomData { to: client.id, teams: false, config: true, flags: false} + + response.extend( + info.left_teams + .iter() + .map(|name| TeamRemove(name.clone()).send(client.id)), + ); + } + } + } + + let nicks: Vec<_> = server + .clients + .iter_mut() + .filter(|(_, c)| c.room_id == Some(room_id)) + .map(|(_, c)| { + c.set_is_ready(c.is_master()); + c.set_is_joined_mid_game(false); + c + }) + .filter_map(|c| { + if !c.is_master() { + Some(c.nick.clone()) + } else { + None + } + }) + .collect(); + + if !nicks.is_empty() { + let msg = if room.protocol_number < 38 { + LegacyReady(false, nicks) + } else { + ClientFlags("-r".to_string(), nicks) + }; + response.add(msg.send_all().in_room(room_id)); + } +} + #[cfg(test)] mod tests { use super::*;