implement maxteams and teamchat messages
authoralfadur
Thu, 11 Apr 2019 19:30:22 +0300
changeset 14793 6dea1ca64992
parent 14792 0e64acbc3f8b
child 14794 18240b308505
implement maxteams and teamchat messages
rust/hedgewars-server/src/server/actions.rs
rust/hedgewars-server/src/server/handlers.rs
rust/hedgewars-server/src/server/handlers/inroom.rs
rust/hedgewars-server/src/server/room.rs
--- a/rust/hedgewars-server/src/server/actions.rs	Thu Apr 11 01:42:14 2019 +0300
+++ b/rust/hedgewars-server/src/server/actions.rs	Thu Apr 11 19:30:22 2019 +0300
@@ -16,18 +16,19 @@
 #[cfg(feature = "official-server")]
 use super::database;
 
-pub enum DestinationRoom {
+pub enum DestinationGroup {
     All,
     Lobby,
     Room(RoomId),
+    Protocol(u16),
 }
 
 pub enum Destination {
     ToId(ClientId),
+    ToIds(Vec<ClientId>),
     ToSelf,
     ToAll {
-        room_id: DestinationRoom,
-        protocol: Option<u16>,
+        group: DestinationGroup,
         skip_self: bool,
     },
 }
@@ -45,6 +46,13 @@
         }
     }
 
+    pub fn send_many(message: HWServerMessage, client_ids: Vec<ClientId>) -> PendingMessage {
+        PendingMessage {
+            destination: Destination::ToIds(client_ids),
+            message,
+        }
+    }
+
     pub fn send_self(message: HWServerMessage) -> PendingMessage {
         PendingMessage {
             destination: Destination::ToSelf,
@@ -54,8 +62,7 @@
 
     pub fn send_all(message: HWServerMessage) -> PendingMessage {
         let destination = Destination::ToAll {
-            room_id: DestinationRoom::All,
-            protocol: None,
+            group: DestinationGroup::All,
             skip_self: false,
         };
         PendingMessage {
@@ -65,31 +72,22 @@
     }
 
     pub fn in_room(mut self, clients_room_id: RoomId) -> PendingMessage {
-        if let Destination::ToAll {
-            ref mut room_id, ..
-        } = self.destination
-        {
-            *room_id = DestinationRoom::Room(clients_room_id)
+        if let Destination::ToAll { ref mut group, .. } = self.destination {
+            *group = DestinationGroup::Room(clients_room_id)
         }
         self
     }
 
     pub fn in_lobby(mut self) -> PendingMessage {
-        if let Destination::ToAll {
-            ref mut room_id, ..
-        } = self.destination
-        {
-            *room_id = DestinationRoom::Lobby
+        if let Destination::ToAll { ref mut group, .. } = self.destination {
+            *group = DestinationGroup::Lobby
         }
         self
     }
 
     pub fn with_protocol(mut self, protocol_number: u16) -> PendingMessage {
-        if let Destination::ToAll {
-            ref mut protocol, ..
-        } = self.destination
-        {
-            *protocol = Some(protocol_number)
+        if let Destination::ToAll { ref mut group, .. } = self.destination {
+            *group = DestinationGroup::Protocol(protocol_number)
         }
         self
     }
@@ -109,6 +107,9 @@
     pub fn send(self, client_id: ClientId) -> PendingMessage {
         PendingMessage::send(self, client_id)
     }
+    pub fn send_many(self, client_ids: Vec<ClientId>) -> PendingMessage {
+        PendingMessage::send_many(self, client_ids)
+    }
     pub fn send_self(self) -> PendingMessage {
         PendingMessage::send_self(self)
     }
--- a/rust/hedgewars-server/src/server/handlers.rs	Thu Apr 11 01:42:14 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers.rs	Thu Apr 11 19:30:22 2019 +0300
@@ -2,7 +2,7 @@
 use std::{collections::HashMap, io, io::Write};
 
 use super::{
-    actions::{Destination, DestinationRoom},
+    actions::{Destination, DestinationGroup},
     core::HWServer,
     coretypes::{ClientId, Replay, RoomId},
     room::RoomSave,
@@ -130,7 +130,7 @@
     ) -> impl Iterator<Item = (Vec<ClientId>, HWServerMessage)> + 'a {
         let client_id = self.client_id;
         self.messages.drain(..).map(move |m| {
-            let ids = get_recipients(server, client_id, &m.destination);
+            let ids = get_recipients(server, client_id, m.destination);
             (ids, m.message)
         })
     }
@@ -159,34 +159,29 @@
 fn get_recipients(
     server: &HWServer,
     client_id: ClientId,
-    destination: &Destination,
+    destination: Destination,
 ) -> Vec<ClientId> {
-    let mut ids = match *destination {
+    match destination {
         Destination::ToSelf => vec![client_id],
         Destination::ToId(id) => vec![id],
-        Destination::ToAll {
-            room_id: DestinationRoom::Lobby,
-            ..
-        } => server.collect_lobby_clients(),
-        Destination::ToAll {
-            room_id: DestinationRoom::Room(id),
-            ..
-        } => server.collect_room_clients(id),
-        Destination::ToAll {
-            protocol: Some(proto),
-            ..
-        } => server.protocol_clients(proto),
-        Destination::ToAll { .. } => server.clients.iter().map(|(id, _)| id).collect::<Vec<_>>(),
-    };
-    if let Destination::ToAll {
-        skip_self: true, ..
-    } = destination
-    {
-        if let Some(index) = ids.iter().position(|id| *id == client_id) {
-            ids.remove(index);
+        Destination::ToIds(ids) => ids,
+        Destination::ToAll { group, skip_self } => {
+            let mut ids = match group {
+                DestinationGroup::All => server.clients.iter().map(|(id, _)| id).collect(),
+                DestinationGroup::Lobby => server.collect_lobby_clients(),
+                DestinationGroup::Protocol(proto) => server.protocol_clients(proto),
+                DestinationGroup::Room(id) => server.collect_room_clients(id),
+            };
+
+            if skip_self {
+                if let Some(index) = ids.iter().position(|id| *id == client_id) {
+                    ids.remove(index);
+                }
+            }
+
+            ids
         }
     }
-    ids
 }
 
 pub fn handle(
--- a/rust/hedgewars-server/src/server/handlers/inroom.rs	Thu Apr 11 01:42:14 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers/inroom.rs	Thu Apr 11 19:30:22 2019 +0300
@@ -11,7 +11,7 @@
         core::HWServer,
         coretypes,
         coretypes::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM},
-        room::{HWRoom, RoomFlags},
+        room::{HWRoom, RoomFlags, MAX_TEAMS_IN_ROOM},
     },
     utils::is_name_illegal,
 };
@@ -133,6 +133,18 @@
                 .in_room(room_id),
             );
         }
+        TeamChat(msg) => {
+            let room = &server.rooms[room_id];
+            if let Some(ref info) = room.game_info {
+                if let Some(clan_color) = room.find_team_color(client_id) {
+                    let client = &server.clients[client_id];
+                    let engine_msg =
+                        to_engine_msg(format!("b{}]{}\x20\x20", client.nick, msg).bytes());
+                    let team = room.clan_team_owners(clan_color).collect();
+                    response.add(ForwardEngineMessage(vec![engine_msg]).send_many(team))
+                }
+            }
+        }
         Fix => {
             if client.is_admin() {
                 room.set_is_fixed(true);
@@ -151,6 +163,16 @@
                 room.greeting = text;
             }
         }
+        MaxTeams(count) => {
+            if !client.is_master() {
+                response.add(Warning("You're not the room master!".to_string()).send_self());
+            } else if count < 2 || count > MAX_TEAMS_IN_ROOM {
+                response
+                    .add(Warning("/maxteams: specify number from 2 to 8".to_string()).send_self());
+            } else {
+                server.rooms[room_id].max_teams = count;
+            }
+        }
         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());
@@ -192,7 +214,7 @@
             }
         }
         AddTeam(mut info) => {
-            if room.teams.len() >= room.team_limit as usize {
+            if room.teams.len() >= room.max_teams 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());
--- a/rust/hedgewars-server/src/server/room.rs	Thu Apr 11 01:42:14 2019 +0300
+++ b/rust/hedgewars-server/src/server/room.rs	Thu Apr 11 19:30:22 2019 +0300
@@ -10,8 +10,8 @@
 use serde_yaml;
 use std::{collections::HashMap, iter};
 
-const MAX_TEAMS_IN_ROOM: u8 = 8;
-const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_HEDGEHOGS_PER_TEAM * MAX_HEDGEHOGS_PER_TEAM;
+pub const MAX_TEAMS_IN_ROOM: u8 = 8;
+pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_HEDGEHOGS_PER_TEAM * MAX_HEDGEHOGS_PER_TEAM;
 
 fn client_teams_impl(
     teams: &[(ClientId, TeamInfo)],
@@ -77,7 +77,7 @@
 
     pub players_number: u8,
     pub default_hedgehog_number: u8,
-    pub team_limit: u8,
+    pub max_teams: u8,
     pub ready_players_number: u8,
     pub teams: Vec<(ClientId, TeamInfo)>,
     config: RoomConfig,
@@ -98,7 +98,7 @@
             protocol_number: 0,
             players_number: 0,
             default_hedgehog_number: 4,
-            team_limit: MAX_TEAMS_IN_ROOM,
+            max_teams: MAX_TEAMS_IN_ROOM,
             ready_players_number: 0,
             teams: Vec::new(),
             config: RoomConfig::new(),
@@ -197,6 +197,13 @@
             .collect()
     }
 
+    pub fn clan_team_owners(&self, color: u8) -> impl Iterator<Item = ClientId> + '_ {
+        self.teams
+            .iter()
+            .filter(move |(_, t)| t.color == color)
+            .map(|(id, _)| *id)
+    }
+
     pub fn find_team_owner(&self, team_name: &str) -> Option<(ClientId, &str)> {
         self.teams
             .iter()