# HG changeset patch # User alfadur # Date 1555006841 -10800 # Node ID 18240b3085058c6681843d348e0b82ec74c8aa23 # Parent 6dea1ca64992db219e92d773c54b1ec030d4dfe9 implement stats message diff -r 6dea1ca64992 -r 18240b308505 rust/hedgewars-server/src/server/core.rs --- a/rust/hedgewars-server/src/server/core.rs Thu Apr 11 19:30:22 2019 +0300 +++ b/rust/hedgewars-server/src/server/core.rs Thu Apr 11 21:20:41 2019 +0300 @@ -158,11 +158,29 @@ .find_map(|(_, c)| Some(c).filter(|c| c.nick == nick)) } + pub fn all_clients(&self) -> impl Iterator + '_ { + self.clients.iter().map(|(id, _)| id) + } + + pub fn filter_clients<'a, F>(&'a self, f: F) -> impl Iterator + 'a + where + F: Fn(&(usize, &HWClient)) -> bool + 'a, + { + self.clients.iter().filter(f).map(|(_, c)| c.id) + } + + pub fn filter_rooms<'a, F>(&'a self, f: F) -> impl Iterator + 'a + where + F: Fn(&(usize, &HWRoom)) -> bool + 'a, + { + self.rooms.iter().filter(f).map(|(_, c)| c.id) + } + pub fn collect_clients(&self, f: F) -> Vec where F: Fn(&(usize, &HWClient)) -> bool, { - self.clients.iter().filter(f).map(|(_, c)| c.id).collect() + self.filter_clients(f).collect() } pub fn collect_nicks(&self, f: F) -> Vec @@ -176,16 +194,20 @@ .collect() } - pub fn collect_lobby_clients(&self) -> Vec { - self.collect_clients(|(_, c)| c.room_id == None) + pub fn lobby_clients(&self) -> impl Iterator + '_ { + self.filter_clients(|(_, c)| c.room_id == None) } - pub fn collect_room_clients(&self, room_id: RoomId) -> Vec { - self.collect_clients(|(_, c)| c.room_id == Some(room_id)) + pub fn room_clients(&self, room_id: RoomId) -> impl Iterator + '_ { + self.filter_clients(move |(_, c)| c.room_id == Some(room_id)) } - pub fn protocol_clients(&self, protocol: u16) -> Vec { - self.collect_clients(|(_, c)| c.protocol_number == protocol) + pub fn protocol_clients(&self, protocol: u16) -> impl Iterator + '_ { + self.filter_clients(move |(_, c)| c.protocol_number == protocol) + } + + pub fn protocol_rooms(&self, protocol: u16) -> impl Iterator + '_ { + self.filter_rooms(move |(_, r)| r.protocol_number == protocol) } pub fn other_clients_in_room(&self, self_id: ClientId) -> Vec { diff -r 6dea1ca64992 -r 18240b308505 rust/hedgewars-server/src/server/handlers.rs --- a/rust/hedgewars-server/src/server/handlers.rs Thu Apr 11 19:30:22 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers.rs Thu Apr 11 21:20:41 2019 +0300 @@ -166,11 +166,11 @@ Destination::ToId(id) => vec![id], 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), + let mut ids: Vec<_> = match group { + DestinationGroup::All => server.all_clients().collect(), + DestinationGroup::Lobby => server.lobby_clients().collect(), + DestinationGroup::Protocol(proto) => server.protocol_clients(proto).collect(), + DestinationGroup::Room(id) => server.room_clients(id).collect(), }; if skip_self { diff -r 6dea1ca64992 -r 18240b308505 rust/hedgewars-server/src/server/handlers/common.rs --- a/rust/hedgewars-server/src/server/handlers/common.rs Thu Apr 11 19:30:22 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers/common.rs Thu Apr 11 21:20:41 2019 +0300 @@ -227,7 +227,8 @@ remove_client_from_room(client, room, response, msg); if !room.is_fixed() && room.master_id == None { - if let Some(new_master_id) = server.collect_room_clients(room_id).first().cloned() { + let new_master_id = server.room_clients(room_id).next(); + if let Some(new_master_id) = new_master_id { let new_master_nick = server.clients[new_master_id].nick.clone(); let room = &mut server.rooms[room_id]; room.master_id = Some(new_master_id); diff -r 6dea1ca64992 -r 18240b308505 rust/hedgewars-server/src/server/handlers/inroom.rs --- a/rust/hedgewars-server/src/server/handlers/inroom.rs Thu Apr 11 19:30:22 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers/inroom.rs Thu Apr 11 21:20:41 2019 +0300 @@ -446,7 +446,7 @@ match error { None => { let msg = voting_description(&kind); - let voting = Voting::new(kind, server.collect_room_clients(client_id)); + let voting = Voting::new(kind, server.room_clients(client_id).collect()); let room = &mut server.rooms[room_id]; room.voting = Some(voting); response.add(server_chat(msg).send_all().in_room(room_id)); diff -r 6dea1ca64992 -r 18240b308505 rust/hedgewars-server/src/server/handlers/lobby.rs --- a/rust/hedgewars-server/src/server/handlers/lobby.rs Thu Apr 11 19:30:22 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers/lobby.rs Thu Apr 11 21:20:41 2019 +0300 @@ -3,7 +3,8 @@ use super::common::rnd_reply; use crate::{ protocol::messages::{ - add_flags, remove_flags, HWProtocolMessage, HWServerMessage::*, ProtocolFlags as Flags, + add_flags, remove_flags, server_chat, HWProtocolMessage, HWServerMessage::*, + ProtocolFlags as Flags, }, server::{ client::HWClient, @@ -13,6 +14,7 @@ utils::is_name_illegal, }; use log::*; +use std::{collections::HashSet, convert::identity}; pub fn handle( server: &mut HWServer, @@ -130,6 +132,31 @@ Rnd(v) => { response.add(rnd_reply(&v).send_self()); } + Stats => { + let mut protocols: HashSet<_> = server + .clients + .iter() + .map(|(_, c)| c.protocol_number) + .chain(server.rooms.iter().map(|(_, r)| r.protocol_number)) + .collect(); + let mut protocols: Vec<_> = protocols.drain().collect(); + protocols.sort(); + + let mut html = Vec::with_capacity(protocols.len() + 2); + + html.push("".to_string()); + for protocol in protocols { + html.push(format!( + "", + super::utils::protocol_version_string(protocol), + server.protocol_clients(protocol).count(), + server.protocol_rooms(protocol).count() + )); + } + html.push("
{}{}{}
".to_string()); + + response.add(Warning(html.join("")).send_self()); + } List => warn!("Deprecated LIST message received"), _ => warn!("Incorrect command in lobby state"), }