rust/hedgewars-server/src/server/handlers/common.rs
changeset 14688 4569d8d50286
parent 14687 5122c584804e
child 14689 aae29ba56aec
--- 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<String>,
     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<String>,
     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<bool> {
+fn add_vote(room: &mut HWRoom, response: &mut Response, vote: Vote) -> Option<bool> {
     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::*;