move start_game into the server
authoralfadur
Mon, 28 Oct 2019 23:17:35 +0300
changeset 15497 395be40faa51
parent 15496 3dc01bbcd0d8
child 15498 6a880692afbc
move start_game into the server
rust/hedgewars-server/src/core/server.rs
rust/hedgewars-server/src/handlers/common.rs
rust/hedgewars-server/src/handlers/inroom.rs
--- a/rust/hedgewars-server/src/core/server.rs	Mon Oct 28 20:40:46 2019 +0100
+++ b/rust/hedgewars-server/src/core/server.rs	Mon Oct 28 23:17:35 2019 +0300
@@ -59,6 +59,14 @@
 }
 
 #[derive(Debug)]
+pub enum StartGameError {
+    NotEnoughClans,
+    NotEnoughTeams,
+    NotReady,
+    AlreadyInGame,
+}
+
+#[derive(Debug)]
 pub struct UninitializedError();
 #[derive(Debug)]
 pub struct AccessError();
@@ -407,6 +415,32 @@
         }
     }
 
+    pub fn start_game(&mut self, room_id: RoomId) -> Result<Vec<String>, StartGameError> {
+        let (room_clients, room_nicks): (Vec<_>, Vec<_>) = self
+            .clients
+            .iter()
+            .map(|(id, c)| (id, c.nick.clone()))
+            .unzip();
+
+        let room = &mut self.rooms[room_id];
+
+        if !room.has_multiple_clans() {
+            Err(StartGameError::NotEnoughClans)
+        } else if room.protocol_number <= 43 && room.players_number != room.ready_players_number {
+            Err(StartGameError::NotReady)
+        } else if room.game_info.is_some() {
+            Err(StartGameError::AlreadyInGame)
+        } else {
+            room.start_round();
+            for id in room_clients {
+                let c = &mut self.clients[id];
+                c.set_is_in_game(true);
+                c.team_indices = room.client_team_indices(c.id);
+            }
+            Ok(room_nicks)
+        }
+    }
+
     #[inline]
     pub fn set_var(&mut self, client_id: ClientId, var: ServerVar) -> Result<(), AccessError> {
         if self.clients[client_id].is_admin() {
--- a/rust/hedgewars-server/src/handlers/common.rs	Mon Oct 28 20:40:46 2019 +0100
+++ b/rust/hedgewars-server/src/handlers/common.rs	Mon Oct 28 23:17:35 2019 +0300
@@ -2,7 +2,7 @@
     core::{
         client::HwClient,
         room::HwRoom,
-        server::{HwServer, JoinRoomError, LeaveRoomResult},
+        server::{HwServer, JoinRoomError, LeaveRoomError, LeaveRoomResult, StartGameError},
         types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType},
     },
     protocol::messages::{
@@ -76,7 +76,7 @@
             .rooms
             .iter()
             .filter(|(_, r)| r.protocol_number == client.protocol_number)
-            .flat_map(|(_, r)| r.info(r.master_id.map(|id| &server.clients[id])))
+            .flat_map(|(_, r)| r.info(r.master_id.map(|id| server.client(id))))
             .collect(),
     );
 
@@ -194,7 +194,7 @@
     }
 }
 
-pub fn get_room_leave_data(
+pub fn get_room_leave_result(
     server: &HwServer,
     room: &HwRoom,
     leave_message: &str,
@@ -260,19 +260,30 @@
     }
 }
 
+pub fn get_room_leave_data(
+    server: &HwServer,
+    room_id: RoomId,
+    leave_message: &str,
+    result: Result<LeaveRoomResult, LeaveRoomError>,
+    response: &mut Response,
+) {
+    match result {
+        Ok(result) => {
+            let room = server.room(room_id);
+            get_room_leave_result(server, room, leave_message, result, response)
+        }
+        Err(_) => (),
+    }
+}
+
 pub fn remove_client(server: &mut HwServer, response: &mut Response, msg: String) {
     let client_id = response.client_id();
     let client = server.client(client_id);
     let nick = client.nick.clone();
 
     if let Some(room_id) = client.room_id {
-        match server.leave_room(client_id) {
-            Ok(result) => {
-                let room = server.room(room_id);
-                super::common::get_room_leave_data(server, room, &msg, result, response)
-            }
-            Err(_) => (),
-        }
+        let result = server.leave_room(client_id);
+        get_room_leave_data(server, room_id, &msg, result, response);
     }
 
     server.remove_client(client_id);
@@ -334,17 +345,13 @@
         response.add(
             ClientFlags(
                 add_flags(&[Flags::RoomMaster]),
-                vec![server.clients[id].nick.clone()],
+                vec![server.client(id).nick.clone()],
             )
             .send(to_client),
         );
     }
-    let nicks: Vec<_> = server
-        .clients
-        .iter()
-        .filter(|(_, c)| c.room_id == Some(room_id) && c.is_ready())
-        .map(|(_, c)| c.nick.clone())
-        .collect();
+    let nicks = server.collect_nicks(|(_, c)| c.room_id == Some(room_id) && c.is_ready());
+
     if !nicks.is_empty() {
         response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client));
     }
@@ -362,15 +369,8 @@
                 if client.room_id == Some(room_id) {
                     let id = client.id;
                     response.add(Kicked.send(id));
-                    match server.leave_room(response.client_id) {
-                        Ok(result) => {
-                            let room = server.room(room_id);
-                            super::common::get_room_leave_data(
-                                server, room, "kicked", result, response,
-                            )
-                        }
-                        Err(_) => (),
-                    }
+                    let result = server.leave_room(id);
+                    get_room_leave_data(server, room_id, "kicked", result, response);
                 }
             }
         }
@@ -384,7 +384,7 @@
                 );
                 let room = &server.rooms[room_id];
                 let room_master = if let Some(id) = room.master_id {
-                    Some(&server.clients[id])
+                    Some(server.client(id))
                 } else {
                     None
                 };
@@ -461,10 +461,10 @@
 
 pub fn submit_vote(server: &mut HwServer, vote: Vote, response: &mut Response) {
     let client_id = response.client_id;
-    let client = &server.clients[client_id];
+    let client = server.client(client_id);
 
     if let Some(room_id) = client.room_id {
-        let room = &mut server.rooms[room_id];
+        let room = server.room_mut(room_id);
 
         if let Some(res) = add_vote(room, response, vote) {
             response.add(
@@ -480,42 +480,31 @@
     }
 }
 
-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];
+pub fn get_start_game_data(
+    server: &HwServer,
+    room_id: RoomId,
+    result: Result<Vec<String>, StartGameError>,
+    response: &mut Response,
+) {
+    match result {
+        Ok(room_nicks) => {
+            let room = server.room(room_id);
+            response.add(RunGame.send_all().in_room(room.id));
+            response.add(
+                ClientFlags(add_flags(&[Flags::InGame]), room_nicks)
+                    .send_all()
+                    .in_room(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(true);
-            c.team_indices = room.client_team_indices(c.id);
+            let room_master = room.master_id.map(|id| server.client(id));
+            get_room_update(None, room, room_master, response);
         }
-        response.add(RunGame.send_all().in_room(room.id));
-        response.add(
-            ClientFlags(add_flags(&[Flags::InGame]), 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);
+        Err(StartGameError::NotEnoughClans) => {
+            response.warn("The game can't be started with less than two clans!")
+        }
+        Err(StartGameError::NotEnoughTeams) => (),
+        Err(StartGameError::NotReady) => response.warn("Not all players are ready"),
+        Err(StartGameErrror) => response.warn("The game is already in progress"),
     }
 }
 
--- a/rust/hedgewars-server/src/handlers/inroom.rs	Mon Oct 28 20:40:46 2019 +0100
+++ b/rust/hedgewars-server/src/handlers/inroom.rs	Mon Oct 28 23:17:35 2019 +0300
@@ -2,7 +2,9 @@
 use crate::{
     core::{
         room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM},
-        server::{ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult},
+        server::{
+            ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, StartGameError,
+        },
         types,
         types::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM},
     },
@@ -117,13 +119,8 @@
                 None => "part".to_string(),
             };
 
-            match server.leave_room(client_id) {
-                Ok(result) => {
-                    let room = server.room(room_id);
-                    super::common::get_room_leave_data(server, room, &msg, result, response)
-                }
-                Err(_) => (),
-            }
+            let result = server.leave_room(client_id);
+            super::common::get_room_leave_data(server, room_id, &msg, result, response);
         }
         Chat(msg) => {
             response.add(
@@ -151,11 +148,15 @@
                 room.set_join_restriction(false);
                 room.set_team_add_restriction(false);
                 room.set_unregistered_players_restriction(true);
+            } else {
+                response.warn(ACCESS_DENIED)
             }
         }
         Unfix => {
             if client.is_admin() {
                 room.set_is_fixed(false);
+            } else {
+                response.warn(ACCESS_DENIED)
             }
         }
         Greeting(text) => {
@@ -206,7 +207,8 @@
             client.set_is_ready(!client.is_ready());
 
             if room.is_fixed() && room.ready_players_number == room.players_number {
-                super::common::start_game(server, room_id, response);
+                let result = server.start_game(room_id);
+                super::common::get_start_game_data(server, room_id, result, response);
             }
         }
         AddTeam(mut info) => {
@@ -480,7 +482,8 @@
             }
         }
         StartGame => {
-            super::common::start_game(server, room_id, response);
+            let result = server.start_game(room_id);
+            super::common::get_start_game_data(server, room_id, result, response);
         }
         EngineMessage(em) => {
             if client.teams_in_game > 0 {