fix client removal
authoralfadur
Thu, 07 Feb 2019 22:26:56 +0300
changeset 14696 8a45c90f4580
parent 14695 216d39de1a44
child 14697 f64e21f164a5
fix client removal
rust/hedgewars-server/src/server/core.rs
rust/hedgewars-server/src/server/handlers.rs
rust/hedgewars-server/src/server/handlers/common.rs
rust/hedgewars-server/src/server/handlers/loggingin.rs
rust/hedgewars-server/src/server/network.rs
--- a/rust/hedgewars-server/src/server/core.rs	Thu Feb 07 18:04:53 2019 +0300
+++ b/rust/hedgewars-server/src/server/core.rs	Thu Feb 07 22:26:56 2019 +0300
@@ -1,14 +1,11 @@
 use super::{
-    actions,
-    actions::{Destination, PendingMessage},
     client::HWClient,
     coretypes::{ClientId, RoomId},
-    handlers,
     indexslab::IndexSlab,
     io::HWServerIO,
     room::HWRoom,
 };
-use crate::{protocol::messages::*, utils};
+use crate::utils;
 
 use log::*;
 use slab;
@@ -45,7 +42,11 @@
 
     pub fn remove_client(&mut self, client_id: ClientId) -> Option<HWAnteClient> {
         let mut client = self.clients.remove(client_id);
-        if let Some(HWAnteClient { web_password: Some(ref mut password), ..}) = client {
+        if let Some(HWAnteClient {
+            web_password: Some(ref mut password),
+            ..
+        }) = client
+        {
             password.replace_range(.., "🦔🦔🦔🦔🦔🦔🦔🦔");
         }
         client
@@ -55,8 +56,6 @@
 pub struct HWServer {
     pub clients: IndexSlab<HWClient>,
     pub rooms: Slab<HWRoom>,
-    pub output: Vec<(Vec<ClientId>, HWServerMessage)>,
-    pub removed_clients: Vec<ClientId>,
     pub io: Box<dyn HWServerIO>,
     pub anteroom: HWAnteroom,
 }
@@ -68,8 +67,6 @@
         Self {
             clients,
             rooms,
-            output: vec![],
-            removed_clients: vec![],
             io,
             anteroom: HWAnteroom::new(clients_limit),
         }
@@ -83,10 +80,7 @@
     }
 
     pub fn remove_client(&mut self, client_id: ClientId) {
-        self.removed_clients.push(client_id);
-        if self.clients.contains(client_id) {
-            self.clients.remove(client_id);
-        }
+        self.clients.remove(client_id);
     }
 
     pub fn add_room(&mut self) -> &mut HWRoom {
--- a/rust/hedgewars-server/src/server/handlers.rs	Thu Feb 07 18:04:53 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers.rs	Thu Feb 07 22:26:56 2019 +0300
@@ -26,6 +26,7 @@
 pub struct Response {
     client_id: ClientId,
     messages: Vec<PendingMessage>,
+    removed_clients: Vec<ClientId>,
 }
 
 impl Response {
@@ -33,12 +34,13 @@
         Self {
             client_id,
             messages: vec![],
+            removed_clients: vec![],
         }
     }
 
     #[inline]
     pub fn is_empty(&self) -> bool {
-        self.messages.is_empty()
+        self.messages.is_empty() && self.removed_clients.is_empty()
     }
 
     #[inline]
@@ -66,6 +68,14 @@
             (ids, m.message)
         })
     }
+
+    pub fn remove_client(&mut self, client_id: ClientId) {
+        self.removed_clients.push(client_id);
+    }
+
+    pub fn extract_removed_clients(&mut self) -> impl Iterator<Item = ClientId> + '_ {
+        self.removed_clients.drain(..)
+    }
 }
 
 impl Extend<PendingMessage> for Response {
@@ -130,6 +140,7 @@
                     }
                     LoginResult::Exit => {
                         server.anteroom.remove_client(client_id);
+                        response.remove_client(client_id);
                     }
                 }
             } else {
@@ -162,5 +173,7 @@
 }
 
 pub fn handle_client_loss(server: &mut HWServer, client_id: ClientId, response: &mut Response) {
-    common::remove_client(server, response, "Connection reset".to_string());
+    if server.anteroom.remove_client(client_id).is_none() {
+        common::remove_client(server, response, "Connection reset".to_string());
+    }
 }
--- a/rust/hedgewars-server/src/server/handlers/common.rs	Thu Feb 07 18:04:53 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers/common.rs	Thu Feb 07 22:26:56 2019 +0300
@@ -226,6 +226,7 @@
 
     response.add(LobbyLeft(nick, msg.to_string()).send_all());
     response.add(Bye("User quit: ".to_string() + &msg).send_self());
+    response.remove_client(client_id);
 }
 
 pub fn get_room_update(
--- a/rust/hedgewars-server/src/server/handlers/loggingin.rs	Thu Feb 07 18:04:53 2019 +0300
+++ b/rust/hedgewars-server/src/server/handlers/loggingin.rs	Thu Feb 07 22:26:56 2019 +0300
@@ -97,7 +97,9 @@
         HWProtocolMessage::Password(hash, salt) => {
             let client = &anteroom.clients[client_id];
 
-            if let (Some(protocol), Some(password)) = (client.protocol_number, client.web_password.as_ref()) {
+            if let (Some(protocol), Some(password)) =
+                (client.protocol_number, client.web_password.as_ref())
+            {
                 let client_hash = get_hash(protocol.get(), &password, &salt, &client.server_salt);
                 let server_hash = get_hash(protocol.get(), &password, &client.server_salt, &salt);
                 if client_hash == server_hash {
--- a/rust/hedgewars-server/src/server/network.rs	Thu Feb 07 18:04:53 2019 +0300
+++ b/rust/hedgewars-server/src/server/network.rs	Thu Feb 07 22:26:56 2019 +0300
@@ -330,7 +330,7 @@
         client_id
     }
 
-    fn flush_server_messages(&mut self, mut response: handlers::Response) {
+    fn flush_server_messages(&mut self, mut response: handlers::Response, poll: &Poll) {
         debug!("{} pending server messages", response.len());
         let output = response.extract_messages(&mut self.server);
         for (clients, message) in output {
@@ -344,6 +344,10 @@
                 }
             }
         }
+
+        for client_id in response.extract_removed_clients() {
+            self.deregister_client(poll, client_id);
+        }
     }
 
     fn create_client_socket(&self, socket: TcpStream) -> io::Result<ClientSocket> {
@@ -381,7 +385,7 @@
         handlers::handle_client_accept(&mut self.server, client_id, &mut response);
 
         if !response.is_empty() {
-            self.flush_server_messages(response);
+            self.flush_server_messages(response, poll);
         }
 
         Ok(())
@@ -438,14 +442,7 @@
         }
 
         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();
-            for client_id in ids {
-                self.deregister_client(poll, client_id);
-            }
+            self.flush_server_messages(response, poll);
         }
 
         Ok(())
@@ -476,7 +473,7 @@
         self.deregister_client(poll, client_id);
         let mut response = handlers::Response::new(client_id);
         handlers::handle_client_loss(&mut self.server, client_id, &mut response);
-        self.flush_server_messages(response);
+        self.flush_server_messages(response, poll);
 
         Ok(())
     }