# HG changeset patch # User alfadur # Date 1549297341 -10800 # Node ID 6e6632068a336101e1e6e62c822cb47ac24c1121 # Parent 455865ccd36c219e48d3b013f0233cae7b05069c Server action refactoring part 3 of N diff -r 455865ccd36c -r 6e6632068a33 rust/hedgewars-server/src/server/core.rs --- a/rust/hedgewars-server/src/server/core.rs Sat Feb 02 15:06:39 2019 +0300 +++ b/rust/hedgewars-server/src/server/core.rs Mon Feb 04 19:22:21 2019 +0300 @@ -93,38 +93,13 @@ move_to_room(&mut self.clients[client_id], &mut self.rooms[room_id]) } - fn get_recipients(&self, client_id: ClientId, destination: &Destination) -> Vec { - let mut ids = match *destination { - Destination::ToSelf => vec![client_id], - Destination::ToId(id) => vec![id], - Destination::ToAll { - room_id: Some(id), .. - } => self.room_clients(id), - Destination::ToAll { - protocol: Some(proto), - .. - } => self.protocol_clients(proto), - Destination::ToAll { .. } => self.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); - } - } - ids - } - pub fn send( &mut self, client_id: ClientId, destination: &Destination, message: HWServerMessage, ) { - let ids = self.get_recipients(client_id, &destination); - self.output.push((ids, message)); + } pub fn send_msg(&mut self, client_id: ClientId, message: PendingMessage) { diff -r 455865ccd36c -r 6e6632068a33 rust/hedgewars-server/src/server/handlers.rs --- a/rust/hedgewars-server/src/server/handlers.rs Sat Feb 02 15:06:39 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers.rs Mon Feb 04 19:22:21 2019 +0300 @@ -2,12 +2,12 @@ use std::{io, io::Write}; use super::{ - actions::{Action, Action::*}, + actions::{Action, Action::*, Destination}, core::HWServer, coretypes::ClientId, }; use crate::{ - protocol::messages::{HWProtocolMessage, HWServerMessage::*}, + protocol::messages::{HWProtocolMessage, HWServerMessage, HWServerMessage::*}, server::actions::PendingMessage, }; use log::*; @@ -31,13 +31,64 @@ } } + #[inline] + pub fn is_empty(&self) -> bool { + self.messages.is_empty() + } + + #[inline] + pub fn len(&self) -> usize { + self.messages.len() + } + + #[inline] pub fn client_id(&self) -> ClientId { self.client_id } + #[inline] pub fn add(&mut self, message: PendingMessage) { self.messages.push(message) } + + pub fn extract_messages<'a, 'b: 'a>( + &'b mut self, + server: &'a HWServer, + ) -> 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); + (ids, m.message) + }) + } +} + +fn get_recipients( + server: &HWServer, + client_id: ClientId, + destination: &Destination, +) -> Vec { + let mut ids = match *destination { + Destination::ToSelf => vec![client_id], + Destination::ToId(id) => vec![id], + Destination::ToAll { + room_id: Some(id), .. + } => server.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); + } + } + ids } pub fn handle( @@ -49,13 +100,12 @@ match message { HWProtocolMessage::Ping => { response.add(Pong.send_self()); - server.react(client_id, vec![Pong.send_self().action()]) } HWProtocolMessage::Quit(Some(msg)) => { - server.react(client_id, vec![ByeClient("User quit: ".to_string() + &msg)]) + //ByeClient("User quit: ".to_string() + &msg) } HWProtocolMessage::Quit(None) => { - server.react(client_id, vec![ByeClient("User quit".to_string())]) + //ByeClient("User quit".to_string()) } HWProtocolMessage::Malformed => warn!("Malformed/unknown message"), HWProtocolMessage::Empty => warn!("Empty message"), diff -r 455865ccd36c -r 6e6632068a33 rust/hedgewars-server/src/server/handlers/lobby.rs --- a/rust/hedgewars-server/src/server/handlers/lobby.rs Sat Feb 02 15:06:39 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers/lobby.rs Mon Feb 04 19:22:21 2019 +0300 @@ -21,12 +21,12 @@ use crate::protocol::messages::HWProtocolMessage::*; match message { CreateRoom(name, password) => { - let actions = if is_name_illegal(&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())] + if is_name_illegal(&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()); } else if server.has_room(&name) { - vec![Warn( - "A room with the same name already exists.".to_string(), - )] + response.add( + Warning("A room with the same name already exists.".to_string()).send_self(), + ); } else { let flags_msg = ClientFlags( "+hr".to_string(), @@ -45,20 +45,18 @@ response.add(flags_msg.send_self()); response.add(ClientFlags("+i".to_string(), vec![client.nick.clone()]).send_self()); - vec![] }; - server.react(client_id, actions); } Chat(msg) => { - let actions = vec![ChatMsg { - nick: server.clients[client_id].nick.clone(), - msg, - } - .send_all() - .in_room(server.lobby_id) - .but_self() - .action()]; - server.react(client_id, actions); + response.add( + ChatMsg { + nick: server.clients[client_id].nick.clone(), + msg, + } + .send_all() + .in_room(server.lobby_id) + .but_self(), + ); } JoinRoom(name, _password) => { let room = server.rooms.iter().find(|(_, r)| r.name == name); @@ -71,17 +69,21 @@ .collect(); let c = &mut server.clients[client_id]; - let actions = if let Some((_, r)) = room { + if let Some((_, r)) = room { if c.protocol_number != r.protocol_number { - vec![Warn( - "Room version incompatible to your Hedgewars version!".to_string(), - )] + response.add( + Warning("Room version incompatible to your Hedgewars version!".to_string()) + .send_self(), + ); } else if r.is_join_restricted() { - vec![Warn( - "Access denied. This room currently doesn't allow joining.".to_string(), - )] + response.add( + Warning( + "Access denied. This room currently doesn't allow joining.".to_string(), + ) + .send_self(), + ); } else if r.players_number == u8::max_value() { - vec![Warn("This room is already full".to_string())] + response.add(Warning("This room is already full".to_string()).send_self()); } else if let Some(room_id) = room_id { let nick = c.nick.clone(); server.move_to_room(client_id, room_id); @@ -101,18 +103,13 @@ .send_self(), ); } - - vec![] - } else { - vec![] } } else { - vec![Warn("No such room.".to_string())] - }; - server.react(client_id, actions); + response.add(Warning("No such room.".to_string()).send_self()); + } } Rnd(v) => { - server.react(client_id, vec![rnd_reply(&v).send_self().action()]); + response.add(rnd_reply(&v).send_self()); } List => warn!("Deprecated LIST message received"), _ => warn!("Incorrect command in lobby state"), diff -r 455865ccd36c -r 6e6632068a33 rust/hedgewars-server/src/server/handlers/loggingin.rs --- a/rust/hedgewars-server/src/server/handlers/loggingin.rs Sat Feb 02 15:06:39 2019 +0300 +++ b/rust/hedgewars-server/src/server/handlers/loggingin.rs Mon Feb 04 19:22:21 2019 +0300 @@ -46,30 +46,17 @@ HWProtocolMessage::Nick(nick) => { let client = &mut server.clients[client_id]; debug!("{} {}", nick, is_name_illegal(&nick)); - let actions = if client.room_id != None { + if client.room_id != None { unreachable!() } else if !client.nick.is_empty() { - vec![ProtocolError("Nickname already provided.".to_string())] + response.add(Error("Nickname already provided.".to_string()).send_self()); } else if is_name_illegal(&nick) { - vec![ByeClient("Illegal nickname! Nicknames 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())] + // ByeClient("Illegal nickname! Nicknames 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 { client.nick = nick.clone(); - vec![Nick(nick).send_self().action(), CheckRegistered] - }; - - server.react(client_id, actions); - } - HWProtocolMessage::Proto(proto) => { - let client = &mut server.clients[client_id]; - let actions = if client.protocol_number != 0 { - vec![ProtocolError("Protocol already known.".to_string())] - } else if proto == 0 { - vec![ProtocolError("Bad number.".to_string())] - } else { - client.protocol_number = proto; - vec![Proto(proto).send_self().action(), CheckRegistered] - }; - server.react(client_id, actions); + response.add(Nick(nick).send_self()); + //CheckRegistered + } } #[cfg(feature = "official-server")] HWProtocolMessage::Password(hash, salt) => { @@ -77,17 +64,24 @@ let client_hash = get_hash(c, &salt, &c.server_salt); let server_hash = get_hash(c, &c.server_salt, &salt); - let actions = if client_hash == server_hash { - vec![ - ServerAuth(format!("{:x}", server_hash)) - .send_self() - .action(), - JoinLobby, - ] + if client_hash == server_hash { + response.add(ServerAuth(format!("{:x}", server_hash)).send_self()); + //JoinLobby } else { - vec![ByeClient("Authentication failed".to_string())] + //ByeClient("Authentication failed".to_string()) }; - server.react(client_id, actions); + } + HWProtocolMessage::Proto(proto) => { + let client = &mut server.clients[client_id]; + if client.protocol_number != 0 { + response.add(Error("Protocol already known.".to_string()).send_self()); + } else if proto == 0 { + response.add(Error("Bad number.".to_string()).send_self()); + } else { + client.protocol_number = proto; + response.add(Proto(proto).send_self()); + // CheckRegistered + } } #[cfg(feature = "official-server")] HWProtocolMessage::Checker(protocol, nick, password) => { diff -r 455865ccd36c -r 6e6632068a33 rust/hedgewars-server/src/server/network.rs --- a/rust/hedgewars-server/src/server/network.rs Sat Feb 02 15:06:39 2019 +0300 +++ b/rust/hedgewars-server/src/server/network.rs Mon Feb 04 19:22:21 2019 +0300 @@ -327,9 +327,10 @@ entry.insert(client); } - fn flush_server_messages(&mut self) { - debug!("{} pending server messages", self.server.output.len()); - for (clients, message) in self.server.output.drain(..) { + fn flush_server_messages(&mut self, mut response: handlers::Response) { + debug!("{} pending server messages", response.len()); + let output = response.extract_messages(&mut self.server); + for (clients, message) in output { debug!("Message {:?} to {:?}", message, clients); let msg_string = message.to_raw_protocol(); for client_id in clients { @@ -377,7 +378,7 @@ self.create_client_socket(client_socket)?, addr, ); - self.flush_server_messages(); + //TODO: create response for initial messages Ok(()) } @@ -432,7 +433,9 @@ )?, } - self.flush_server_messages(); + if !response.is_empty() { + self.flush_server_messages(response); + } if !self.server.removed_clients.is_empty() { let ids: Vec<_> = self.server.removed_clients.drain(..).collect();