# HG changeset patch # User alfadur # Date 1555000222 -10800 # Node ID 6dea1ca64992db219e92d773c54b1ec030d4dfe9 # Parent 0e64acbc3f8bd1a485ef733f69a6f5d02d6ef4bc implement maxteams and teamchat messages diff -r 0e64acbc3f8b -r 6dea1ca64992 rust/hedgewars-server/src/server/actions.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), ToSelf, ToAll { - room_id: DestinationRoom, - protocol: Option, + group: DestinationGroup, skip_self: bool, }, } @@ -45,6 +46,13 @@ } } + pub fn send_many(message: HWServerMessage, client_ids: Vec) -> 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) -> PendingMessage { + PendingMessage::send_many(self, client_ids) + } pub fn send_self(self) -> PendingMessage { PendingMessage::send_self(self) } diff -r 0e64acbc3f8b -r 6dea1ca64992 rust/hedgewars-server/src/server/handlers.rs --- 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, 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 { - 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::>(), - }; - 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( diff -r 0e64acbc3f8b -r 6dea1ca64992 rust/hedgewars-server/src/server/handlers/inroom.rs --- 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()); diff -r 0e64acbc3f8b -r 6dea1ca64992 rust/hedgewars-server/src/server/room.rs --- 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 + '_ { + 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()