--- 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<Item = ClientId> + '_ {
+ self.clients.iter().map(|(id, _)| id)
+ }
+
+ pub fn filter_clients<'a, F>(&'a self, f: F) -> impl Iterator<Item = ClientId> + '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<Item = RoomId> + 'a
+ where
+ F: Fn(&(usize, &HWRoom)) -> bool + 'a,
+ {
+ self.rooms.iter().filter(f).map(|(_, c)| c.id)
+ }
+
pub fn collect_clients<F>(&self, f: F) -> Vec<ClientId>
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<F>(&self, f: F) -> Vec<String>
@@ -176,16 +194,20 @@
.collect()
}
- pub fn collect_lobby_clients(&self) -> Vec<ClientId> {
- self.collect_clients(|(_, c)| c.room_id == None)
+ pub fn lobby_clients(&self) -> impl Iterator<Item = ClientId> + '_ {
+ self.filter_clients(|(_, c)| c.room_id == None)
}
- pub fn collect_room_clients(&self, room_id: RoomId) -> Vec<ClientId> {
- self.collect_clients(|(_, c)| c.room_id == Some(room_id))
+ pub fn room_clients(&self, room_id: RoomId) -> impl Iterator<Item = ClientId> + '_ {
+ self.filter_clients(move |(_, c)| c.room_id == Some(room_id))
}
- pub fn protocol_clients(&self, protocol: u16) -> Vec<ClientId> {
- self.collect_clients(|(_, c)| c.protocol_number == protocol)
+ pub fn protocol_clients(&self, protocol: u16) -> impl Iterator<Item = ClientId> + '_ {
+ self.filter_clients(move |(_, c)| c.protocol_number == protocol)
+ }
+
+ pub fn protocol_rooms(&self, protocol: u16) -> impl Iterator<Item = RoomId> + '_ {
+ self.filter_rooms(move |(_, r)| r.protocol_number == protocol)
}
pub fn other_clients_in_room(&self, self_id: ClientId) -> Vec<ClientId> {
--- 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 {
--- 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);
--- 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));
--- 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("<table>".to_string());
+ for protocol in protocols {
+ html.push(format!(
+ "<tr><td>{}</td><td>{}</td><td>{}</td></tr>",
+ super::utils::protocol_version_string(protocol),
+ server.protocol_clients(protocol).count(),
+ server.protocol_rooms(protocol).count()
+ ));
+ }
+ html.push("</table>".to_string());
+
+ response.add(Warning(html.join("")).send_self());
+ }
List => warn!("Deprecated LIST message received"),
_ => warn!("Incorrect command in lobby state"),
}