Implement map voting
authoralfadur
Fri, 20 Jul 2018 00:02:52 +0300
changeset 13527 e3ae9eea0689
parent 13526 3f69acc7e268
child 13528 c8b626b0a3ad
Implement map voting
gameServer2/src/protocol/messages.rs
gameServer2/src/server/actions.rs
gameServer2/src/server/handlers/inroom.rs
gameServer2/src/server/room.rs
--- a/gameServer2/src/protocol/messages.rs	Thu Jul 19 22:50:46 2018 +0300
+++ b/gameServer2/src/protocol/messages.rs	Fri Jul 20 00:02:52 2018 +0300
@@ -105,8 +105,8 @@
     Unreachable,
 }
 
-pub fn server_chat(msg: &str) -> HWServerMessage  {
-    HWServerMessage::ChatMsg{ nick: "[server]".to_string(), msg: msg.to_string() }
+pub fn server_chat(msg: String) -> HWServerMessage  {
+    HWServerMessage::ChatMsg{ nick: "[server]".to_string(), msg }
 }
 
 impl GameCfg {
--- a/gameServer2/src/server/actions.rs	Thu Jul 19 22:50:46 2018 +0300
+++ b/gameServer2/src/server/actions.rs	Fri Jul 20 00:02:52 2018 +0300
@@ -331,11 +331,12 @@
         }
         AddVote{vote, is_forced} => {
             let mut actions = Vec::new();
-            if let (c, Some(r)) = server.client_and_room(client_id) {
+            if let Some(r) = server.room(client_id) {
                 let mut result = None;
                 if let Some(ref mut voting) = r.voting {
                     if is_forced || voting.votes.iter().find(|(id, _)| client_id == *id).is_none() {
-                        actions.push(server_chat("Your vote has been counted.").send_self().action());
+                        actions.push(server_chat("Your vote has been counted.".to_string())
+                            .send_self().action());
                         voting.votes.push((client_id, vote));
                         let i = voting.votes.iter();
                         let pro = i.clone().filter(|(_, v)| *v).count();
@@ -347,14 +348,16 @@
                             result = Some(false);
                         }
                     } else {
-                        actions.push(server_chat("You already have voted.").send_self().action());
+                        actions.push(server_chat("You already have voted.".to_string())
+                            .send_self().action());
                     }
                 } else {
-                    actions.push(server_chat("There's no voting going on.").send_self().action());
+                    actions.push(server_chat("There's no voting going on.".to_string())
+                        .send_self().action());
                 }
 
                 if let Some(res) = result {
-                    actions.push(server_chat("Voting closed.")
+                    actions.push(server_chat("Voting closed.".to_string())
                         .send_all().in_room(r.id).action());
                     let voting = replace(&mut r.voting, None).unwrap();
                     if res {
@@ -378,13 +381,25 @@
                         }
                     }
                 },
-                VoteType::Map(_) => {
-                    unimplemented!();
+                VoteType::Map(None) => (),
+                VoteType::Map(Some(name)) => {
+                    if let Some(location) = server.rooms[room_id].load_config(&name) {
+                        actions.push(server_chat(location.to_string())
+                            .send_all().in_room(room_id).action());
+                        actions.push(SendRoomUpdate(None));
+                        for (_, c) in server.clients.iter() {
+                            if c.room_id == Some(room_id) {
+                               actions.push(SendRoomData{
+                                   to: c.id, teams: false,
+                                   config: true, flags: false})
+                            }
+                        }
+                    }
                 },
                 VoteType::Pause => {
                     if let Some(ref mut info) = server.rooms[room_id].game_info {
                         info.is_paused = !info.is_paused;
-                        actions.push(server_chat("Pause toggled.")
+                        actions.push(server_chat("Pause toggled.".to_string())
                             .send_all().in_room(room_id).action());
                         actions.push(ForwardEngineMessage(vec![to_engine_msg(once(b'I'))])
                             .send_all().in_room(room_id).action());
@@ -531,7 +546,7 @@
         }
         SendTeamRemovalMessage(team_name) => {
             let mut actions = Vec::new();
-            if let (c, Some(r)) = server.client_and_room(client_id) {
+            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());
                     actions.push(ForwardEngineMessage(vec![to_engine_msg(msg)]).
--- a/gameServer2/src/server/handlers/inroom.rs	Thu Jul 19 22:50:46 2018 +0300
+++ b/gameServer2/src/server/handlers/inroom.rs	Fri Jul 20 00:02:52 2018 +0300
@@ -277,7 +277,7 @@
         }
         CallVote(None) => {
             server.react(client_id, vec![
-                server_chat("Available callvote commands: kick <nickname>, map <name>, pause, newseed, hedgehogs <number>")
+                server_chat("Available callvote commands: kick <nickname>, map <name>, pause, newseed, hedgehogs <number>".to_string())
                     .send_self().action()])
         }
         CallVote(Some(kind)) => {
@@ -287,20 +287,29 @@
                     if server.find_client(&nick).filter(|c| c.room_id == Some(room_id)).is_some() {
                         None
                     } else {
-                        Some("/callvote kick: No such user!")
+                        Some("/callvote kick: No such user!".to_string())
                     }
                 },
                 VoteType::Map(None) => {
-                    Some("/callvote map: Not implemented")
+                    let names: Vec<_> = server.rooms[room_id].saves.keys().cloned().collect();
+                    if names.is_empty() {
+                        Some("/callvote map: No maps saved in this room!".to_string())
+                    } else {
+                        Some(format!("Available maps: {}", names.join(", ")))
+                    }
                 },
                 VoteType::Map(Some(name)) => {
-                    Some("/callvote map: Not implemented")
+                    if server.rooms[room_id].saves.get(&name[..]).is_some() {
+                        Some("/callvote map: No such map!".to_string())
+                    } else {
+                        None
+                    }
                 },
                 VoteType::Pause => {
                     if is_in_game {
                         None
                     } else {
-                        Some("/callvote pause: No game in progress!")
+                        Some("/callvote pause: No game in progress!".to_string())
                     }
                 },
                 VoteType::NewSeed => {
@@ -309,7 +318,7 @@
                 VoteType::HedgehogsPerTeam(number) => {
                     match number {
                         1...8 => None,
-                        _ => Some("/callvote hedgehogs: Specify number from 1 to 8.")
+                        _ => Some("/callvote hedgehogs: Specify number from 1 to 8.".to_string())
                     }
                 },
             };
@@ -319,7 +328,7 @@
                     let voting = Voting::new(kind, server.room_clients(client_id));
                     server.rooms[room_id].voting = Some(voting);
                     server.react(client_id, vec![
-                        server_chat(&msg).send_all().in_room(room_id).action(),
+                        server_chat(msg).send_all().in_room(room_id).action(),
                         AddVote{ vote: true, is_forced: false}]);
                 }
                 Some(msg) => {
--- a/gameServer2/src/server/room.rs	Thu Jul 19 22:50:46 2018 +0300
+++ b/gameServer2/src/server/room.rs	Fri Jul 20 00:02:52 2018 +0300
@@ -1,4 +1,6 @@
-use std::{iter};
+use std::{
+    iter, collections::HashMap
+};
 use server::{
     coretypes::{ClientId, RoomId, TeamInfo, GameCfg, GameCfg::*, Voting},
     client::{HWClient}
@@ -107,6 +109,11 @@
     }
 }
 
+pub struct RoomSave {
+    pub location: String,
+    config: RoomConfig
+}
+
 bitflags!{
     pub struct RoomFlags: u8 {
         const FIXED = 0b0000_0001;
@@ -132,6 +139,7 @@
     pub teams: Vec<(ClientId, TeamInfo)>,
     config: RoomConfig,
     pub voting: Option<Voting>,
+    pub saves: HashMap<String, RoomSave>,
     pub game_info: Option<GameInfo>
 }
 
@@ -152,6 +160,7 @@
             teams: Vec::new(),
             config: RoomConfig::new(),
             voting: None,
+            saves: HashMap::new(),
             game_info: None
         }
     }
@@ -326,6 +335,15 @@
         }
     }
 
+    pub fn load_config(&mut self, name: &str) -> Option<&str> {
+        if let Some(save) = self.saves.get(name) {
+            self.config = save.config.clone();
+            Some(&save.location[..])
+        } else {
+            None
+        }
+    }
+
     pub fn team_info(owner: &HWClient, team: &TeamInfo) -> Vec<String> {
         let mut info = vec![
             team.name.clone(),