Server action refactoring part B of N
authoralfadur <mail@none>
Wed, 06 Feb 2019 20:48:40 +0300
changeset 14688 4569d8d50286
parent 14687 5122c584804e
child 14689 aae29ba56aec
Server action refactoring part B of N
rust/hedgewars-server/src/server/actions.rs
rust/hedgewars-server/src/server/handlers/common.rs
rust/hedgewars-server/src/server/handlers/inroom.rs
--- a/rust/hedgewars-server/src/server/actions.rs	Wed Feb 06 00:57:01 2019 +0300
+++ b/rust/hedgewars-server/src/server/actions.rs	Wed Feb 06 20:48:40 2019 +0300
@@ -103,9 +103,7 @@
 
 pub enum Action {
     ChangeMaster(RoomId, Option<ClientId>),
-    StartRoomGame(RoomId),
     SendTeamRemovalMessage(String),
-    FinishRoomGame(RoomId),
     SendRoomData {
         to: ClientId,
         teams: bool,
@@ -229,40 +227,7 @@
                 server.clients[id].set_is_master(true)
             }
         }
-        StartRoomGame(room_id) => {
-            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() {
-                /*Warn(
-                    "The game can't be started with less than two clans!".to_string(),
-                )*/
-            } else if room.protocol_number <= 43 && room.players_number != room.ready_players_number
-            {
-                /*Warn("Not all players are ready".to_string())*/
-            } else if room.game_info.is_some() {
-                /*Warn("The game is already in progress".to_string())*/
-            } 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);
-                }
-                /*RunGame.send_all().in_room(room.id).action(),*/
-                //SendRoomUpdate(None),
-                /*ClientFlags("+g".to_string(), room_nicks)
-                .send_all()
-                .in_room(room.id)
-                .action(),*/
-            }
-        }
         SendTeamRemovalMessage(team_name) => {
-            let mut actions = Vec::new();
             if let Some(r) = server.room(client_id) {
                 if let Some(ref mut info) = r.game_info {
                     let msg = once(b'F').chain(team_name.bytes());
@@ -275,7 +240,7 @@
                     );*/
                     info.teams_in_game -= 1;
                     if info.teams_in_game == 0 {
-                        actions.push(FinishRoomGame(r.id));
+                        //actions.push(FinishRoomGame(r.id));
                     }
                     let remove_msg = to_engine_msg(once(b'F').chain(team_name.bytes()));
                     if let Some(m) = &info.sync_msg {
@@ -295,56 +260,5 @@
                 }
             }
         }
-        FinishRoomGame(room_id) => {
-            let mut actions = Vec::new();
-
-            let r = &mut server.rooms[room_id];
-            r.ready_players_number = 1;
-            //actions.push(SendRoomUpdate(None));
-            //actions.push(RoundFinished.send_all().in_room(r.id).action());
-
-            if let Some(info) = replace(&mut r.game_info, None) {
-                for (_, c) in server.clients.iter() {
-                    if c.room_id == Some(room_id) && c.is_joined_mid_game() {
-                        actions.push(SendRoomData {
-                            to: c.id,
-                            teams: false,
-                            config: true,
-                            flags: false,
-                        });
-                        for name in &info.left_teams {
-                            //actions.push(TeamRemove(name.clone()).send(c.id).action());
-                        }
-                    }
-                }
-            }
-
-            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 r.protocol_number < 38 {
-                    LegacyReady(false, nicks)
-                } else {
-                    ClientFlags("-r".to_string(), nicks)
-                };
-                //actions.push(msg.send_all().in_room(room_id).action());
-            }
-        }
     }
 }
--- 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::*;
--- a/rust/hedgewars-server/src/server/handlers/inroom.rs	Wed Feb 06 00:57:01 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers/inroom.rs	Wed Feb 06 20:48:40 2019 +0300
@@ -155,19 +155,21 @@
         RoomName(new_name) => {
             if is_name_illegal(&new_name) {
                 response.add(Warning("Illegal room name! A room name must be between 1-40 characters long, must not have a trailing or leading space and must not have any of these characters: $()*+?[]^{|}".to_string()).send_self());
-            } else if server.rooms[room_id].is_fixed() {
-                response.add(Warning("Access denied.".to_string()).send_self());
             } else if server.has_room(&new_name) {
                 response.add(
                     Warning("A room with the same name already exists.".to_string()).send_self(),
                 );
             } else {
-                let mut old_name = new_name.clone();
-                let client = &server.clients[client_id];
                 let room = &mut server.rooms[room_id];
-                swap(&mut room.name, &mut old_name);
-                super::common::get_room_update(Some(old_name), room, Some(&client), response);
-            };
+                if room.is_fixed() || room.master_id != Some(client_id) {
+                    response.add(Warning("Access denied.".to_string()).send_self());
+                } else {
+                    let mut old_name = new_name.clone();
+                    let client = &server.clients[client_id];
+                    swap(&mut room.name, &mut old_name);
+                    super::common::get_room_update(Some(old_name), room, Some(&client), response);
+                }
+            }
         }
         ToggleReady => {
             if let (client, Some(room)) = server.client_and_room(client_id) {
@@ -193,50 +195,54 @@
             }
         }
         AddTeam(info) => {
-            if let (client, Some(room)) = server.client_and_room(client_id) {
-                if room.teams.len() >= room.team_limit as usize {
-                    response.add(Warning("Too many teams!".to_string()).send_self());
-                } else if room.addable_hedgehogs() == 0 {
-                    response.add(Warning("Too many hedgehogs!".to_string()).send_self());
-                } else if room.find_team(|t| t.name == info.name) != None {
-                    response.add(
-                        Warning("There's already a team with same name in the list.".to_string())
-                            .send_self(),
-                    );
-                } else if room.game_info.is_some() {
-                    response.add(
-                        Warning("Joining not possible: Round is in progress.".to_string())
-                            .send_self(),
-                    );
-                } else if room.is_team_add_restricted() {
-                    response.add(
-                        Warning("This room currently does not allow adding new teams.".to_string())
-                            .send_self(),
-                    );
+            let client = &mut server.clients[client_id];
+            let room = &mut server.rooms[room_id];
+            if room.teams.len() >= room.team_limit as usize {
+                response.add(Warning("Too many teams!".to_string()).send_self());
+            } else if room.addable_hedgehogs() == 0 {
+                response.add(Warning("Too many hedgehogs!".to_string()).send_self());
+            } else if room.find_team(|t| t.name == info.name) != None {
+                response.add(
+                    Warning("There's already a team with same name in the list.".to_string())
+                        .send_self(),
+                );
+            } else if room.game_info.is_some() {
+                response.add(
+                    Warning("Joining not possible: Round is in progress.".to_string()).send_self(),
+                );
+            } else if room.is_team_add_restricted() {
+                response.add(
+                    Warning("This room currently does not allow adding new teams.".to_string())
+                        .send_self(),
+                );
+            } else {
+                let team = room.add_team(client.id, *info, client.protocol_number < 42);
+                client.teams_in_game += 1;
+                client.clan = Some(team.color);
+                response.add(TeamAccepted(team.name.clone()).send_self());
+                response.add(
+                    TeamAdd(HWRoom::team_info(&client, team))
+                        .send_all()
+                        .in_room(room_id)
+                        .but_self(),
+                );
+                response.add(
+                    TeamColor(team.name.clone(), team.color)
+                        .send_all()
+                        .in_room(room_id),
+                );
+                response.add(
+                    HedgehogsNumber(team.name.clone(), team.hedgehogs_number)
+                        .send_all()
+                        .in_room(room_id),
+                );
+
+                let room_master = if let Some(id) = room.master_id {
+                    Some(&server.clients[id])
                 } else {
-                    let team = room.add_team(client.id, *info, client.protocol_number < 42);
-                    client.teams_in_game += 1;
-                    client.clan = Some(team.color);
-                    response.add(TeamAccepted(team.name.clone()).send_self());
-                    response.add(
-                        TeamAdd(HWRoom::team_info(&client, team))
-                            .send_all()
-                            .in_room(room_id)
-                            .but_self(),
-                    );
-                    response.add(
-                        TeamColor(team.name.clone(), team.color)
-                            .send_all()
-                            .in_room(room_id),
-                    );
-                    response.add(
-                        HedgehogsNumber(team.name.clone(), team.hedgehogs_number)
-                            .send_all()
-                            .in_room(room_id),
-                    );
-
-                    super::common::get_room_update(None, room, Some(&client), response);
-                }
+                    None
+                };
+                super::common::get_room_update(None, room, room_master, response);
             }
         }
         RemoveTeam(name) => {