refactor root handler
authoralfadur
Fri, 04 Oct 2019 23:23:35 +0300
changeset 15465 61a0bd0bb021
parent 15464 96e438b114f0
child 15466 6031c0cfec89
refactor root handler
rust/hedgewars-server/src/core/indexslab.rs
rust/hedgewars-server/src/core/server.rs
rust/hedgewars-server/src/handlers.rs
rust/hedgewars-server/src/handlers/common.rs
rust/hedgewars-server/src/handlers/strings.rs
--- a/rust/hedgewars-server/src/core/indexslab.rs	Tue Oct 01 23:53:09 2019 +0300
+++ b/rust/hedgewars-server/src/core/indexslab.rs	Fri Oct 04 23:23:35 2019 +0300
@@ -19,6 +19,14 @@
         }
     }
 
+    pub fn get(&self, index: usize) -> Option<&T> {
+        self.data[index].as_ref()
+    }
+
+    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
+        self.data[index].as_mut()
+    }
+
     pub fn insert(&mut self, index: usize, value: T) {
         if index >= self.data.len() {
             self.data.reserve(index - self.data.len() + 1);
--- a/rust/hedgewars-server/src/core/server.rs	Tue Oct 01 23:53:09 2019 +0300
+++ b/rust/hedgewars-server/src/core/server.rs	Fri Oct 04 23:23:35 2019 +0300
@@ -14,11 +14,13 @@
 
 type Slab<T> = slab::Slab<T>;
 
+#[derive(Debug)]
 pub enum CreateRoomError {
     InvalidName,
     AlreadyExists,
 }
 
+#[derive(Debug)]
 pub enum JoinRoomError {
     DoesntExist,
     WrongProtocol,
@@ -26,6 +28,9 @@
     Restricted,
 }
 
+#[derive(Debug)]
+pub struct UninitializedError();
+#[derive(Debug)]
 pub struct AccessError();
 
 pub struct HwAnteClient {
@@ -34,6 +39,9 @@
     pub server_salt: String,
     pub is_checker: bool,
     pub is_local_admin: bool,
+    pub is_registered: bool,
+    pub is_admin: bool,
+    pub is_contributor: bool,
 }
 
 pub struct HwAnteroom {
@@ -53,6 +61,9 @@
             server_salt: salt,
             is_checker: false,
             is_local_admin,
+            is_registered: false,
+            is_admin: false,
+            is_contributor: false,
         };
         self.clients.insert(client_id, client);
     }
@@ -106,6 +117,34 @@
         }
     }
 
+    #[inline]
+    pub fn client(&self, client_id: ClientId) -> &HwClient {
+        &self.clients[client_id]
+    }
+
+    #[inline]
+    pub fn client_mut(&mut self, client_id: ClientId) -> &mut HwClient {
+        &mut self.clients[client_id]
+    }
+
+    #[inline]
+    pub fn room(&self, room_id: RoomId) -> &HwRoom {
+        &self.rooms[room_id]
+    }
+
+    #[inline]
+    pub fn room_mut(&mut self, room_id: RoomId) -> &mut HwRoom {
+        &mut self.rooms[room_id]
+    }
+
+    #[inline]
+    pub fn is_admin(&self, client_id: ClientId) -> bool {
+        self.clients
+            .get(client_id)
+            .map(|c| c.is_admin())
+            .unwrap_or(false)
+    }
+
     pub fn add_client(&mut self, client_id: ClientId, data: HwAnteClient) {
         if let (Some(protocol), Some(nick)) = (data.protocol_number, data.nick) {
             let mut client = HwClient::new(client_id, protocol.get(), nick);
@@ -113,6 +152,13 @@
             #[cfg(not(feature = "official-server"))]
             client.set_is_admin(data.is_local_admin);
 
+            #[cfg(feature = "official-server")]
+            {
+                client.set_is_registered(info.is_registered);
+                client.set_is_admin(info.is_admin);
+                client.set_is_contributor(info.is_contributor);
+            }
+
             self.clients.insert(client_id, client);
         }
     }
@@ -121,8 +167,8 @@
         self.clients.remove(client_id);
     }
 
-    pub fn get_greetings(&self, client_id: ClientId) -> &str {
-        if self.clients[client_id].protocol_number < self.latest_protocol {
+    pub fn get_greetings(&self, client: &HwClient) -> &str {
+        if client.protocol_number < self.latest_protocol {
             &self.greetings.for_old_protocols
         } else {
             &self.greetings.for_latest_protocol
--- a/rust/hedgewars-server/src/handlers.rs	Tue Oct 01 23:53:09 2019 +0300
+++ b/rust/hedgewars-server/src/handlers.rs	Fri Oct 04 23:23:35 2019 +0300
@@ -9,6 +9,7 @@
 use self::{
     actions::{Destination, DestinationGroup, PendingMessage},
     inanteroom::LoginResult,
+    strings::*,
 };
 use crate::{
     core::{
@@ -166,6 +167,11 @@
     }
 
     #[inline]
+    pub fn error(&mut self, message: &str) {
+        self.add(Error(message.to_string()).send_self());
+    }
+
+    #[inline]
     pub fn request_io(&mut self, task: IoTask) {
         self.io_tasks.push(task)
     }
@@ -246,7 +252,7 @@
                     LoginResult::Complete => {
                         if let Some(client) = server.anteroom.remove_client(client_id) {
                             server.add_client(client_id, client);
-                            common::join_lobby(server, response);
+                            common::get_lobby_join_data(server, response);
                         }
                     }
                     LoginResult::Exit => {
@@ -268,7 +274,7 @@
                             let master_sign = if client.is_master() { "+" } else { "" };
                             let room_info = match client.room_id {
                                 Some(room_id) => {
-                                    let room = &server.rooms[room_id];
+                                    let room = server.room(room_id);
                                     let status = match room.game_info {
                                         Some(_) if client.teams_in_game == 0 => "(spectating)",
                                         Some(_) => "(playing)",
@@ -290,37 +296,36 @@
                             ];
                             response.add(Info(info).send_self())
                         } else {
-                            response
-                                .add(server_chat("Player is not online.".to_string()).send_self())
+                            response.add(server_chat(USER_OFFLINE.to_string()).send_self())
                         }
                     }
                     HwProtocolMessage::ToggleServerRegisteredOnly => {
-                        if !server.clients[client_id].is_admin() {
-                            response.add(Warning("Access denied.".to_string()).send_self());
+                        if !server.is_admin(client_id) {
+                            response.warn(ACCESS_DENIED);
                         } else {
-                            server.set_is_registered_only(server.is_registered_only());
+                            server.set_is_registered_only(!server.is_registered_only());
                             let msg = if server.is_registered_only() {
-                                "This server no longer allows unregistered players to join."
+                                REGISTERED_ONLY_ENABLED
                             } else {
-                                "This server now allows unregistered players to join."
+                                REGISTERED_ONLY_DISABLED
                             };
                             response.add(server_chat(msg.to_string()).send_all());
                         }
                     }
                     HwProtocolMessage::Global(msg) => {
-                        if !server.clients[client_id].is_admin() {
-                            response.add(Warning("Access denied.".to_string()).send_self());
+                        if !server.is_admin(client_id) {
+                            response.warn(ACCESS_DENIED);
                         } else {
                             response.add(global_chat(msg).send_all())
                         }
                     }
                     HwProtocolMessage::SuperPower => {
-                        if !server.clients[client_id].is_admin() {
-                            response.add(Warning("Access denied.".to_string()).send_self());
+                        let client = server.client_mut(client_id);
+                        if !client.is_admin() {
+                            response.warn(ACCESS_DENIED);
                         } else {
-                            server.clients[client_id].set_has_super_power(true);
-                            response
-                                .add(server_chat("Super power activated.".to_string()).send_self())
+                            client.set_has_super_power(true);
+                            response.add(server_chat(SUPER_POWER.to_string()).send_self())
                         }
                     }
                     HwProtocolMessage::Watch(id) => {
@@ -331,13 +336,10 @@
 
                         #[cfg(not(feature = "official-server"))]
                         {
-                            response.add(
-                                Warning("This server does not support replays!".to_string())
-                                    .send_self(),
-                            );
+                            response.warn(REPLAY_NOT_SUPPORTED);
                         }
                     }
-                    _ => match server.clients[client_id].room_id {
+                    _ => match server.client(client_id).room_id {
                         None => inlobby::handle(server, client_id, response, message),
                         Some(room_id) => {
                             inroom::handle(server, client_id, response, room_id, message)
@@ -380,38 +382,35 @@
     match io_result {
         IoResult::AccountRegistered(is_registered) => {
             if !is_registered && server.is_registered_only() {
-                response.add(
-                    Bye("This server only allows registered users to join.".to_string())
-                        .send_self(),
-                );
+                response.add(Bye(REGISTRATION_REQUIRED.to_string()).send_self());
                 response.remove_client(client_id);
             } else if is_registered {
                 let salt = server.anteroom.clients[client_id].server_salt.clone();
                 response.add(AskPassword(salt).send_self());
             } else if let Some(client) = server.anteroom.remove_client(client_id) {
                 server.add_client(client_id, client);
-                common::join_lobby(server, response);
+                common::get_lobby_join_data(server, response);
             }
         }
         IoResult::Account(Some(info)) => {
             response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self());
-            if let Some(client) = server.anteroom.remove_client(client_id) {
+            if let Some(mut client) = server.anteroom.remove_client(client_id) {
+                client.is_registered = info.is_registered;
+                client.is_admin = info.is_admin;
+                client.is_contributor = info.is_contributor;
                 server.add_client(client_id, client);
-                let client = &mut server.clients[client_id];
-                client.set_is_registered(info.is_registered);
-                client.set_is_admin(info.is_admin);
-                client.set_is_contributor(info.is_contributor);
-                common::join_lobby(server, response);
+                common::get_lobby_join_data(server, response);
             }
         }
         IoResult::Account(None) => {
-            response.add(Error("Authentication failed.".to_string()).send_self());
+            response.error(AUTHENTICATION_FAILED);
             response.remove_client(client_id);
         }
         IoResult::Replay(Some(replay)) => {
-            let protocol = server.clients[client_id].protocol_number;
+            let client = server.client(client_id);
+            let protocol = client.protocol_number;
             let start_msg = if protocol < 58 {
-                RoomJoined(vec![server.clients[client_id].nick.clone()])
+                RoomJoined(vec![client.nick.clone()])
             } else {
                 ReplayStart
             };
@@ -427,32 +426,27 @@
             }
         }
         IoResult::Replay(None) => {
-            response.add(Warning("Could't load the replay".to_string()).send_self())
+            response.warn(REPLAY_LOAD_FAILED);
         }
         IoResult::SaveRoom(_, true) => {
-            response.add(server_chat("Room configs saved successfully.".to_string()).send_self());
+            response.add(server_chat(ROOM_CONFIG_SAVED.to_string()).send_self());
         }
         IoResult::SaveRoom(_, false) => {
-            response.add(Warning("Unable to save the room configs.".to_string()).send_self());
+            response.warn(ROOM_CONFIG_SAVE_FAILED);
         }
         IoResult::LoadRoom(room_id, Some(contents)) => {
             if let Some(ref mut room) = server.rooms.get_mut(room_id) {
                 match room.set_saves(&contents) {
-                    Ok(_) => response.add(
-                        server_chat("Room configs loaded successfully.".to_string()).send_self(),
-                    ),
+                    Ok(_) => response.add(server_chat(ROOM_CONFIG_LOADED.to_string()).send_self()),
                     Err(e) => {
                         warn!("Error while deserializing the room configs: {}", e);
-                        response.add(
-                            Warning("Unable to deserialize the room configs.".to_string())
-                                .send_self(),
-                        );
+                        response.warn(ROOM_CONFIG_DESERIALIZE_FAILED);
                     }
                 }
             }
         }
         IoResult::LoadRoom(_, None) => {
-            response.add(Warning("Unable to load the room configs.".to_string()).send_self());
+            response.warn(ROOM_CONFIG_LOAD_FAILED);
         }
     }
 }
--- a/rust/hedgewars-server/src/handlers/common.rs	Tue Oct 01 23:53:09 2019 +0300
+++ b/rust/hedgewars-server/src/handlers/common.rs	Fri Oct 04 23:23:35 2019 +0300
@@ -35,10 +35,10 @@
     }
 }
 
-pub fn join_lobby(server: &mut HwServer, response: &mut Response) {
+pub fn get_lobby_join_data(server: &HwServer, response: &mut Response) {
     let client_id = response.client_id();
 
-    let client = &server.clients[client_id];
+    let client = server.client(client_id);
     let nick = vec![client.nick.clone()];
     let mut flags = vec![];
     if client.is_registered() {
@@ -69,7 +69,7 @@
         ),
     ];
 
-    let server_msg = ServerMessage(server.get_greetings(client_id).to_string());
+    let server_msg = ServerMessage(server.get_greetings(client).to_string());
 
     let rooms_msg = Rooms(
         server
@@ -338,8 +338,8 @@
 
     server.remove_client(client_id);
 
-    response.add(LobbyLeft(nick, msg.to_string()).send_all());
-    response.add(Bye("User quit: ".to_string() + &msg).send_self());
+    response.add(LobbyLeft(nick, msg.clone()).send_all());
+    response.add(Bye(msg).send_self());
     response.remove_client(client_id);
 }
 
--- a/rust/hedgewars-server/src/handlers/strings.rs	Tue Oct 01 23:53:09 2019 +0300
+++ b/rust/hedgewars-server/src/handlers/strings.rs	Fri Oct 04 23:23:35 2019 +0300
@@ -1,9 +1,23 @@
 pub const ACCESS_DENIED: &str = "Access denied.";
+pub const AUTHENTICATION_FAILED: &str = "Authentication failed.";
 pub const ILLEGAL_ROOM_NAME: &str = "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: $()*+?[]^{|}";
 pub const NO_ROOM: &str = "No such room.";
 pub const NO_USER: &str = "No such user.";
+pub const REPLAY_LOAD_FAILED: &str = "Could't load the replay";
+pub const REPLAY_NOT_SUPPORTED: &str = "This server does not support replays!";
+pub const REGISTRATION_REQUIRED: &str = "This server only allows registered users to join.";
+pub const REGISTERED_ONLY_ENABLED: &str =
+    "This server no longer allows unregistered players to join.";
+pub const REGISTERED_ONLY_DISABLED: &str = "This server now allows unregistered players to join.";
+pub const ROOM_CONFIG_SAVE_FAILED: &str = "Unable to save the room configs.";
+pub const ROOM_CONFIG_LOAD_FAILED: &str = "Unable to load the room configs.";
+pub const ROOM_CONFIG_DESERIALIZE_FAILED: &str = "Unable to deserialize the room configs.";
+pub const ROOM_CONFIG_LOADED: &str = "Room configs loaded successfully.";
+pub const ROOM_CONFIG_SAVED: &str = "Room configs saved successfully.";
 pub const ROOM_EXISTS: &str = "A room with the same name already exists.";
 pub const ROOM_FULL: &str = "This room is already full.";
 pub const ROOM_JOIN_RESTRICTED: &str = "Access denied. This room currently doesn't allow joining.";
+pub const SUPER_POWER: &str = "Super power activated.";
+pub const USER_OFFLINE: &str = "Player is not online.";
 pub const VARIABLE_UPDATED: &str = "Server variable has been updated.";
 pub const WRONG_PROTOCOL: &str = "Room version incompatible to your Hedgewars version!";