# HG changeset patch # User alfadur # Date 1549109199 -10800 # Node ID 455865ccd36c219e48d3b013f0233cae7b05069c # Parent 56831f466d1d6517a5e18c14ea3e7e2e2546ca1a Server action refactoring part 2 of N diff -r 56831f466d1d -r 455865ccd36c rust/hedgewars-server/src/server/actions.rs --- a/rust/hedgewars-server/src/server/actions.rs Fri Jan 25 06:46:13 2019 +0100 +++ b/rust/hedgewars-server/src/server/actions.rs Sat Feb 02 15:06:39 2019 +0300 @@ -115,7 +115,6 @@ Send(PendingMessage), RemoveClient, ByeClient(String), - ReactProtocolMessage(HWProtocolMessage), CheckRegistered, JoinLobby, RemoveRoom(RoomId), @@ -176,7 +175,6 @@ server.clients.remove(client_id); } } - ReactProtocolMessage(msg) => handlers::handle(server, client_id, msg), CheckRegistered => { let client = &server.clients[client_id]; if client.protocol_number > 0 && client.nick != "" { diff -r 56831f466d1d -r 455865ccd36c rust/hedgewars-server/src/server/core.rs --- a/rust/hedgewars-server/src/server/core.rs Fri Jan 25 06:46:13 2019 +0100 +++ b/rust/hedgewars-server/src/server/core.rs Sat Feb 02 15:06:39 2019 +0300 @@ -73,13 +73,6 @@ allocate_room(&mut self.rooms) } - pub fn handle_msg(&mut self, client_id: ClientId, msg: HWProtocolMessage) { - debug!("Handling message {:?} for client {}", msg, client_id); - if self.clients.contains(client_id) { - handlers::handle(self, client_id, msg); - } - } - #[inline] pub fn create_room( &mut self, @@ -95,6 +88,11 @@ ) } + #[inline] + pub fn move_to_room(&mut self, client_id: ClientId, room_id: RoomId) { + 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], @@ -129,6 +127,10 @@ self.output.push((ids, message)); } + pub fn send_msg(&mut self, client_id: ClientId, message: PendingMessage) { + self.send(client_id, &message.destination, message.message) + } + pub fn react(&mut self, client_id: ClientId, actions: Vec) { for action in actions { actions::run_action(self, client_id, action); diff -r 56831f466d1d -r 455865ccd36c rust/hedgewars-server/src/server/handlers.rs --- a/rust/hedgewars-server/src/server/handlers.rs Fri Jan 25 06:46:13 2019 +0100 +++ b/rust/hedgewars-server/src/server/handlers.rs Sat Feb 02 15:06:39 2019 +0300 @@ -6,7 +6,10 @@ core::HWServer, coretypes::ClientId, }; -use crate::protocol::messages::{HWProtocolMessage, HWServerMessage::*}; +use crate::{ + protocol::messages::{HWProtocolMessage, HWServerMessage::*}, + server::actions::PendingMessage, +}; use log::*; mod checker; @@ -15,9 +18,39 @@ mod lobby; mod loggingin; -pub fn handle(server: &mut HWServer, client_id: ClientId, message: HWProtocolMessage) { +pub struct Response { + client_id: ClientId, + messages: Vec, +} + +impl Response { + pub fn new(client_id: ClientId) -> Self { + Self { + client_id, + messages: vec![], + } + } + + pub fn client_id(&self) -> ClientId { + self.client_id + } + + pub fn add(&mut self, message: PendingMessage) { + self.messages.push(message) + } +} + +pub fn handle( + server: &mut HWServer, + client_id: ClientId, + response: &mut Response, + message: HWProtocolMessage, +) { match message { - HWProtocolMessage::Ping => server.react(client_id, vec![Pong.send_self().action()]), + 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)]) } @@ -27,9 +60,11 @@ HWProtocolMessage::Malformed => warn!("Malformed/unknown message"), HWProtocolMessage::Empty => warn!("Empty message"), _ => match server.clients[client_id].room_id { - None => loggingin::handle(server, client_id, message), - Some(id) if id == server.lobby_id => lobby::handle(server, client_id, message), - Some(id) => inroom::handle(server, client_id, id, message), + None => loggingin::handle(server, client_id, response, message), + Some(id) if id == server.lobby_id => { + lobby::handle(server, client_id, response, message) + } + Some(id) => inroom::handle(server, client_id, response, id, message), }, } } diff -r 56831f466d1d -r 455865ccd36c rust/hedgewars-server/src/server/handlers/inroom.rs --- a/rust/hedgewars-server/src/server/handlers/inroom.rs Fri Jan 25 06:46:13 2019 +0100 +++ b/rust/hedgewars-server/src/server/handlers/inroom.rs Sat Feb 02 15:06:39 2019 +0300 @@ -102,6 +102,7 @@ pub fn handle( server: &mut HWServer, client_id: ClientId, + response: &mut super::Response, room_id: RoomId, message: HWProtocolMessage, ) { diff -r 56831f466d1d -r 455865ccd36c rust/hedgewars-server/src/server/handlers/lobby.rs --- a/rust/hedgewars-server/src/server/handlers/lobby.rs Fri Jan 25 06:46:13 2019 +0100 +++ b/rust/hedgewars-server/src/server/handlers/lobby.rs Sat Feb 02 15:06:39 2019 +0300 @@ -12,7 +12,12 @@ }; use log::*; -pub fn handle(server: &mut HWServer, client_id: ClientId, message: HWProtocolMessage) { +pub fn handle( + server: &mut HWServer, + client_id: ClientId, + response: &mut super::Response, + message: HWProtocolMessage, +) { use crate::protocol::messages::HWProtocolMessage::*; match message { CreateRoom(name, password) => { @@ -32,15 +37,17 @@ let room = &server.rooms[room_id]; let client = &server.clients[client_id]; - vec![ + response.add( RoomAdd(room.info(Some(&client))) .send_all() - .with_protocol(room.protocol_number) - .action(), - flags_msg.send_self().action(), - ] + .with_protocol(room.protocol_number), + ); + response.add(flags_msg.send_self()); + + response.add(ClientFlags("+i".to_string(), vec![client.nick.clone()]).send_self()); + vec![] }; - server.react(client_id, actions) + server.react(client_id, actions); } Chat(msg) => { let actions = vec![ChatMsg { @@ -75,8 +82,29 @@ )] } else if r.players_number == u8::max_value() { vec![Warn("This room is already full".to_string())] + } else if let Some(room_id) = room_id { + let nick = c.nick.clone(); + server.move_to_room(client_id, room_id); + + response.add(RoomJoined(vec![nick.clone()]).send_all().in_room(room_id)); + response.add(ClientFlags("+i".to_string(), vec![nick]).send_all()); + response.add(RoomJoined(nicks).send_self()); + + let room = &server.rooms[room_id]; + + if !room.greeting.is_empty() { + response.add( + ChatMsg { + nick: "[greeting]".to_string(), + msg: room.greeting.clone(), + } + .send_self(), + ); + } + + vec![] } else { - vec![MoveToRoom(r.id), RoomJoined(nicks).send_self().action()] + vec![] } } else { vec![Warn("No such room.".to_string())] diff -r 56831f466d1d -r 455865ccd36c rust/hedgewars-server/src/server/handlers/loggingin.rs --- a/rust/hedgewars-server/src/server/handlers/loggingin.rs Fri Jan 25 06:46:13 2019 +0100 +++ b/rust/hedgewars-server/src/server/handlers/loggingin.rs Sat Feb 02 15:06:39 2019 +0300 @@ -36,7 +36,12 @@ Sha1Digest(sha1(s.as_bytes())) } -pub fn handle(server: &mut HWServer, client_id: ClientId, message: HWProtocolMessage) { +pub fn handle( + server: &mut HWServer, + client_id: ClientId, + response: &mut super::Response, + message: HWProtocolMessage, +) { match message { HWProtocolMessage::Nick(nick) => { let client = &mut server.clients[client_id]; diff -r 56831f466d1d -r 455865ccd36c rust/hedgewars-server/src/server/network.rs --- a/rust/hedgewars-server/src/server/network.rs Fri Jan 25 06:46:13 2019 +0100 +++ b/rust/hedgewars-server/src/server/network.rs Sat Feb 02 15:06:39 2019 +0300 @@ -16,7 +16,7 @@ use netbuf; use slab::Slab; -use super::{core::HWServer, coretypes::ClientId, io::FileServerIO}; +use super::{core::HWServer, coretypes::ClientId, handlers, io::FileServerIO}; use crate::{ protocol::{messages::*, ProtocolDecoder}, utils, @@ -178,7 +178,7 @@ let result = loop { match buf_out.write_to(destination) { Ok(bytes) if buf_out.is_empty() || bytes == 0 => { - break Ok(((), NetworkClientState::Idle)) + break Ok(((), NetworkClientState::Idle)); } Ok(_) => (), Err(ref error) @@ -406,10 +406,15 @@ Ok((Vec::new(), NetworkClientState::Idle)) }; + let mut response = handlers::Response::new(client_id); + match messages { Ok((messages, state)) => { for message in messages { - self.server.handle_msg(client_id, message); + debug!("Handling message {:?} for client {}", message, client_id); + if self.server.clients.contains(client_id) { + handlers::handle(&mut self.server, client_id, &mut response, message); + } } match state { NetworkClientState::NeedsRead => {