--- 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<ClientId> {
- 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::<Vec<_>>(),
- };
- 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) {
--- 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<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);
+ (ids, m.message)
+ })
+ }
+}
+
+fn get_recipients(
+ server: &HWServer,
+ client_id: ClientId,
+ destination: &Destination,
+) -> Vec<ClientId> {
+ 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::<Vec<_>>(),
+ };
+ 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"),
--- 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"),
--- 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) => {
--- 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();