Add room flags
authoralfadur
Tue, 17 Jul 2018 00:27:24 +0300
changeset 13494 8c5dd562c9f7
parent 13493 282e5e54386f
child 13500 5359ff75da3a
Add room flags
gameServer2/src/server/actions.rs
gameServer2/src/server/handlers/inroom.rs
gameServer2/src/server/handlers/lobby.rs
gameServer2/src/server/room.rs
--- a/gameServer2/src/server/actions.rs	Mon Jul 16 22:59:58 2018 +0300
+++ b/gameServer2/src/server/actions.rs	Tue Jul 17 00:27:24 2018 +0300
@@ -5,7 +5,7 @@
 };
 use super::{
     server::HWServer,
-    room::GameInfo,
+    room::{GameInfo, RoomFlags},
     client::HWClient,
     coretypes::{ClientId, RoomId, GameCfg, VoteType},
     room::HWRoom,
@@ -414,7 +414,7 @@
                 if c.is_ready() && r.ready_players_number > 0 {
                     r.ready_players_number -= 1;
                 }
-                if c.is_master() && (r.players_number > 0 || r.is_fixed) {
+                if c.is_master() && (r.players_number > 0 || r.is_fixed()) {
                     actions.push(ChangeMaster(r.id, None));
                 }
                 actions.push(ClientFlags("-i".to_string(), vec![c.nick.clone()])
@@ -425,7 +425,7 @@
 
             if let (c, Some(r)) = server.client_and_room(client_id) {
                 c.room_id = Some(lobby_id);
-                if r.players_number == 0 && !r.is_fixed {
+                if r.players_number == 0 && !r.is_fixed() {
                     actions.push(RemoveRoom(r.id));
                 } else {
                     actions.push(RemoveClientTeams);
@@ -439,7 +439,7 @@
         ChangeMaster(room_id, new_id) => {
             let mut actions = Vec::new();
             let room_client_ids = server.room_clients(room_id);
-            let new_id = if server.room(client_id).map(|r| r.is_fixed).unwrap_or(false) {
+            let new_id = if server.room(client_id).map(|r| r.is_fixed()).unwrap_or(false) {
                 new_id
             } else {
                 new_id.or_else(||
@@ -459,6 +459,10 @@
                     None => {}
                 }
                 r.master_id = new_id;
+                r.set_join_restriction(false);
+                r.set_team_add_restriction(false);
+                let is_fixed = r.is_fixed();
+                r.set_unregistered_players_restriction(is_fixed);
                 if let Some(nick) = new_nick {
                     actions.push(ClientFlags("+h".to_string(), vec![nick])
                         .send_all().in_room(r.id).action());
--- a/gameServer2/src/server/handlers/inroom.rs	Mon Jul 16 22:59:58 2018 +0300
+++ b/gameServer2/src/server/handlers/inroom.rs	Tue Jul 17 00:27:24 2018 +0300
@@ -8,7 +8,7 @@
 use server::{
     coretypes::{ClientId, RoomId, Voting, VoteType},
     server::HWServer,
-    room::HWRoom,
+    room::{HWRoom, RoomFlags},
     actions::{Action, Action::*}
 };
 use utils::is_name_illegal;
@@ -81,6 +81,16 @@
     })
 }
 
+fn room_message_flag(msg: &HWProtocolMessage) -> RoomFlags {
+    use protocol::messages::HWProtocolMessage::*;
+    match msg {
+        ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN,
+        ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD,
+        ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS,
+        _ => RoomFlags::empty()
+    }
+}
+
 pub fn handle(server: &mut HWServer, client_id: ClientId, room_id: RoomId, message: HWProtocolMessage) {
     use protocol::messages::HWProtocolMessage::*;
     match message {
@@ -98,17 +108,17 @@
         },
         Fix => {
             if let (c, Some(r)) = server.client_and_room(client_id) {
-                if c.is_admin() { r.is_fixed = true }
+                if c.is_admin() { r.set_is_fixed(true) }
             }
         }
         Unfix => {
             if let (c, Some(r)) = server.client_and_room(client_id) {
-                if c.is_admin() { r.is_fixed = false }
+                if c.is_admin() { r.set_is_fixed(false) }
             }
         }
         Greeting(text) => {
             if let (c, Some(r)) = server.client_and_room(client_id) {
-                if c.is_admin() || c.is_master() && !r.is_fixed {
+                if c.is_admin() || c.is_master() && !r.is_fixed() {
                     r.greeting = text
                 }
             }
@@ -117,7 +127,7 @@
             let actions =
                 if is_name_illegal(&new_name) {
                     vec![Warn("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())]
-                } else if server.room(client_id).map(|r| r.is_fixed).unwrap_or(false) {
+                } else if server.room(client_id).map(|r| r.is_fixed()).unwrap_or(false) {
                     vec![Warn("Access denied.".to_string())]
                 } else if server.has_room(&new_name) {
                     vec![Warn("A room with the same name already exists.".to_string())]
@@ -146,7 +156,7 @@
                 let mut v =
                     vec![ClientFlags(flags.to_string(), vec![c.nick.clone()])
                         .send_all().in_room(r.id).action()];
-                if r.is_fixed && r.ready_players_number as u32 == r.players_number {
+                if r.is_fixed() && r.ready_players_number == r.players_number {
                     v.push(StartRoomGame(r.id))
                 }
                 v
@@ -166,6 +176,8 @@
                     actions.push(Warn("There's already a team with same name in the list.".to_string()))
                 } else if r.game_info.is_some() {
                     actions.push(Warn("Joining not possible: Round is in progress.".to_string()))
+                } else if r.is_team_add_restricted() {
+                    actions.push(Warn("This room currently does not allow adding new teams.".to_string()));
                 } else {
                     let team = r.add_team(c.id, info);
                     c.teams_in_game += 1;
@@ -252,7 +264,7 @@
         },
         Cfg(cfg) => {
             let actions = if let (c, Some(r)) = server.client_and_room(client_id) {
-                if r.is_fixed {
+                if r.is_fixed() {
                     vec![Warn("Access denied.".to_string())]
                 } else if !c.is_master() {
                     vec![ProtocolError("You're not the room master!".to_string())]
@@ -336,6 +348,12 @@
             };
             server.react(client_id, actions);
         }
+        ToggleRestrictJoin | ToggleRestrictTeams | ToggleRegisteredOnly  => {
+            if server.clients[client_id].is_master() {
+                server.rooms[room_id].flags.toggle(room_message_flag(&message));
+            }
+            server.react(client_id, vec![SendRoomUpdate(None)]);
+        }
         StartGame => {
             let actions = if let (_, Some(r)) = server.client_and_room(client_id) {
                 vec![StartRoomGame(r.id)]
--- a/gameServer2/src/server/handlers/lobby.rs	Mon Jul 16 22:59:58 2018 +0300
+++ b/gameServer2/src/server/handlers/lobby.rs	Tue Jul 17 00:27:24 2018 +0300
@@ -49,6 +49,10 @@
                 actions = if let Some((_, r)) = room {
                     if c.protocol_number != r.protocol_number {
                         vec![Warn("Room version incompatible to your Hedgewars version!".to_string())]
+                    } else if r.is_join_restricted() {
+                        vec![Warn("Access denied. This room currently doesn't allow joining.".to_string())]
+                    } else if r.players_number == u8::max_value() {
+                        vec![Warn("This room is already full".to_string())]
                     } else {
                         vec![MoveToRoom(r.id),
                              RoomJoined(nicks).send_self().action()]
--- a/gameServer2/src/server/room.rs	Mon Jul 16 22:59:58 2018 +0300
+++ b/gameServer2/src/server/room.rs	Tue Jul 17 00:27:24 2018 +0300
@@ -106,16 +106,25 @@
     }
 }
 
+bitflags!{
+    pub struct RoomFlags: u8 {
+        const FIXED = 0b0000_0001;
+        const RESTRICTED_JOIN = 0b0000_0010;
+        const RESTRICTED_TEAM_ADD = 0b0000_0100;
+        const RESTRICTED_UNREGISTERED_PLAYERS = 0b0000_1000;
+    }
+}
+
 pub struct HWRoom {
     pub id: RoomId,
     pub master_id: Option<ClientId>,
     pub name: String,
     pub password: Option<String>,
+    pub greeting: String,
     pub protocol_number: u16,
-    pub greeting: String,
-    pub is_fixed: bool,
+    pub flags: RoomFlags,
 
-    pub players_number: u32,
+    pub players_number: u8,
     pub default_hedgehog_number: u8,
     pub team_limit: u8,
     pub ready_players_number: u8,
@@ -133,7 +142,7 @@
             name: String::new(),
             password: None,
             greeting: "".to_string(),
-            is_fixed: false,
+            flags: RoomFlags::empty(),
             protocol_number: 0,
             players_number: 0,
             default_hedgehog_number: 4,
@@ -250,11 +259,47 @@
         }
     }
 
+    pub fn is_fixed(&self) -> bool {
+        self.flags.contains(RoomFlags::FIXED)
+    }
+    pub fn is_join_restricted(&self) -> bool {
+        self.flags.contains(RoomFlags::RESTRICTED_JOIN)
+    }
+    pub fn is_team_add_restricted(&self) -> bool {
+        self.flags.contains(RoomFlags::RESTRICTED_TEAM_ADD)
+    }
+    pub fn are_unregistered_players_restricted(&self) -> bool {
+        self.flags.contains(RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS)
+    }
+
+    pub fn set_is_fixed(&mut self, value: bool) {
+        self.flags.set(RoomFlags::FIXED, value)
+    }
+    pub fn set_join_restriction(&mut self, value: bool) {
+        self.flags.set(RoomFlags::RESTRICTED_JOIN, value)
+    }
+    pub fn set_team_add_restriction(&mut self, value: bool) {
+        self.flags.set(RoomFlags::RESTRICTED_TEAM_ADD, value)
+    }
+    pub fn set_unregistered_players_restriction(&mut self, value: bool) {
+        self.flags.set(RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS, value)
+    }
+
+    fn flags_string(&self) -> String {
+        let mut result = "-".to_string();
+        if self.game_info.is_some()  { result += "g" }
+        if self.password.is_some()   { result += "p" }
+        if self.is_join_restricted() { result += "j" }
+        if self.are_unregistered_players_restricted() {
+            result += "r"
+        }
+        result
+    }
+
     pub fn info(&self, master: Option<&HWClient>) -> Vec<String> {
-        let flags = "-".to_string();
         let c = &self.config;
         vec![
-            flags,
+            self.flags_string(),
             self.name.clone(),
             self.players_number.to_string(),
             self.teams.len().to_string(),