rust/hedgewars-server/src/handlers.rs
branchui-scaling
changeset 15685 d92eeb468dad
parent 15465 61a0bd0bb021
child 15504 4cc9ec732392
equal deleted inserted replaced
15304:c4fd2813b127 15685:d92eeb468dad
     7 };
     7 };
     8 
     8 
     9 use self::{
     9 use self::{
    10     actions::{Destination, DestinationGroup, PendingMessage},
    10     actions::{Destination, DestinationGroup, PendingMessage},
    11     inanteroom::LoginResult,
    11     inanteroom::LoginResult,
       
    12     strings::*,
    12 };
    13 };
    13 use crate::{
    14 use crate::{
    14     core::{
    15     core::{
    15         room::RoomSave,
    16         room::RoomSave,
    16         server::HwServer,
    17         server::HwServer,
    30 mod checker;
    31 mod checker;
    31 mod common;
    32 mod common;
    32 mod inanteroom;
    33 mod inanteroom;
    33 mod inlobby;
    34 mod inlobby;
    34 mod inroom;
    35 mod inroom;
       
    36 mod strings;
    35 
    37 
    36 #[derive(PartialEq, Debug)]
    38 #[derive(PartialEq, Debug)]
    37 pub struct Sha1Digest([u8; 20]);
    39 pub struct Sha1Digest([u8; 20]);
    38 
    40 
    39 impl Sha1Digest {
    41 impl Sha1Digest {
   155     }
   157     }
   156 
   158 
   157     #[inline]
   159     #[inline]
   158     pub fn add(&mut self, message: PendingMessage) {
   160     pub fn add(&mut self, message: PendingMessage) {
   159         self.messages.push(message)
   161         self.messages.push(message)
       
   162     }
       
   163 
       
   164     #[inline]
       
   165     pub fn warn(&mut self, message: &str) {
       
   166         self.add(Warning(message.to_string()).send_self());
       
   167     }
       
   168 
       
   169     #[inline]
       
   170     pub fn error(&mut self, message: &str) {
       
   171         self.add(Error(message.to_string()).send_self());
   160     }
   172     }
   161 
   173 
   162     #[inline]
   174     #[inline]
   163     pub fn request_io(&mut self, task: IoTask) {
   175     pub fn request_io(&mut self, task: IoTask) {
   164         self.io_tasks.push(task)
   176         self.io_tasks.push(task)
   238                 match inanteroom::handle(server, client_id, response, message) {
   250                 match inanteroom::handle(server, client_id, response, message) {
   239                     LoginResult::Unchanged => (),
   251                     LoginResult::Unchanged => (),
   240                     LoginResult::Complete => {
   252                     LoginResult::Complete => {
   241                         if let Some(client) = server.anteroom.remove_client(client_id) {
   253                         if let Some(client) = server.anteroom.remove_client(client_id) {
   242                             server.add_client(client_id, client);
   254                             server.add_client(client_id, client);
   243                             common::join_lobby(server, response);
   255                             common::get_lobby_join_data(server, response);
   244                         }
   256                         }
   245                     }
   257                     }
   246                     LoginResult::Exit => {
   258                     LoginResult::Exit => {
   247                         server.anteroom.remove_client(client_id);
   259                         server.anteroom.remove_client(client_id);
   248                         response.remove_client(client_id);
   260                         response.remove_client(client_id);
   260                         if let Some(client) = server.find_client(&nick) {
   272                         if let Some(client) = server.find_client(&nick) {
   261                             let admin_sign = if client.is_admin() { "@" } else { "" };
   273                             let admin_sign = if client.is_admin() { "@" } else { "" };
   262                             let master_sign = if client.is_master() { "+" } else { "" };
   274                             let master_sign = if client.is_master() { "+" } else { "" };
   263                             let room_info = match client.room_id {
   275                             let room_info = match client.room_id {
   264                                 Some(room_id) => {
   276                                 Some(room_id) => {
   265                                     let room = &server.rooms[room_id];
   277                                     let room = server.room(room_id);
   266                                     let status = match room.game_info {
   278                                     let status = match room.game_info {
   267                                         Some(_) if client.teams_in_game == 0 => "(spectating)",
   279                                         Some(_) if client.teams_in_game == 0 => "(spectating)",
   268                                         Some(_) => "(playing)",
   280                                         Some(_) => "(playing)",
   269                                         None => "",
   281                                         None => "",
   270                                     };
   282                                     };
   282                                 utils::protocol_version_string(client.protocol_number).to_string(),
   294                                 utils::protocol_version_string(client.protocol_number).to_string(),
   283                                 room_info,
   295                                 room_info,
   284                             ];
   296                             ];
   285                             response.add(Info(info).send_self())
   297                             response.add(Info(info).send_self())
   286                         } else {
   298                         } else {
   287                             response
   299                             response.add(server_chat(USER_OFFLINE.to_string()).send_self())
   288                                 .add(server_chat("Player is not online.".to_string()).send_self())
       
   289                         }
   300                         }
   290                     }
   301                     }
   291                     HwProtocolMessage::ToggleServerRegisteredOnly => {
   302                     HwProtocolMessage::ToggleServerRegisteredOnly => {
   292                         if !server.clients[client_id].is_admin() {
   303                         if !server.is_admin(client_id) {
   293                             response.add(Warning("Access denied.".to_string()).send_self());
   304                             response.warn(ACCESS_DENIED);
   294                         } else {
   305                         } else {
   295                             server.set_is_registered_only(server.is_registered_only());
   306                             server.set_is_registered_only(!server.is_registered_only());
   296                             let msg = if server.is_registered_only() {
   307                             let msg = if server.is_registered_only() {
   297                                 "This server no longer allows unregistered players to join."
   308                                 REGISTERED_ONLY_ENABLED
   298                             } else {
   309                             } else {
   299                                 "This server now allows unregistered players to join."
   310                                 REGISTERED_ONLY_DISABLED
   300                             };
   311                             };
   301                             response.add(server_chat(msg.to_string()).send_all());
   312                             response.add(server_chat(msg.to_string()).send_all());
   302                         }
   313                         }
   303                     }
   314                     }
   304                     HwProtocolMessage::Global(msg) => {
   315                     HwProtocolMessage::Global(msg) => {
   305                         if !server.clients[client_id].is_admin() {
   316                         if !server.is_admin(client_id) {
   306                             response.add(Warning("Access denied.".to_string()).send_self());
   317                             response.warn(ACCESS_DENIED);
   307                         } else {
   318                         } else {
   308                             response.add(global_chat(msg).send_all())
   319                             response.add(global_chat(msg).send_all())
   309                         }
   320                         }
   310                     }
   321                     }
   311                     HwProtocolMessage::SuperPower => {
   322                     HwProtocolMessage::SuperPower => {
   312                         if !server.clients[client_id].is_admin() {
   323                         let client = server.client_mut(client_id);
   313                             response.add(Warning("Access denied.".to_string()).send_self());
   324                         if !client.is_admin() {
       
   325                             response.warn(ACCESS_DENIED);
   314                         } else {
   326                         } else {
   315                             server.clients[client_id].set_has_super_power(true);
   327                             client.set_has_super_power(true);
   316                             response
   328                             response.add(server_chat(SUPER_POWER.to_string()).send_self())
   317                                 .add(server_chat("Super power activated.".to_string()).send_self())
       
   318                         }
   329                         }
   319                     }
   330                     }
   320                     HwProtocolMessage::Watch(id) => {
   331                     HwProtocolMessage::Watch(id) => {
   321                         #[cfg(feature = "official-server")]
   332                         #[cfg(feature = "official-server")]
   322                         {
   333                         {
   323                             response.request_io(IoTask::GetReplay { id })
   334                             response.request_io(IoTask::GetReplay { id })
   324                         }
   335                         }
   325 
   336 
   326                         #[cfg(not(feature = "official-server"))]
   337                         #[cfg(not(feature = "official-server"))]
   327                         {
   338                         {
   328                             response.add(
   339                             response.warn(REPLAY_NOT_SUPPORTED);
   329                                 Warning("This server does not support replays!".to_string())
   340                         }
   330                                     .send_self(),
   341                     }
   331                             );
   342                     _ => match server.client(client_id).room_id {
   332                         }
       
   333                     }
       
   334                     _ => match server.clients[client_id].room_id {
       
   335                         None => inlobby::handle(server, client_id, response, message),
   343                         None => inlobby::handle(server, client_id, response, message),
   336                         Some(room_id) => {
   344                         Some(room_id) => {
   337                             inroom::handle(server, client_id, response, room_id, message)
   345                             inroom::handle(server, client_id, response, room_id, message)
   338                         }
   346                         }
   339                     },
   347                     },
   372     io_result: IoResult,
   380     io_result: IoResult,
   373 ) {
   381 ) {
   374     match io_result {
   382     match io_result {
   375         IoResult::AccountRegistered(is_registered) => {
   383         IoResult::AccountRegistered(is_registered) => {
   376             if !is_registered && server.is_registered_only() {
   384             if !is_registered && server.is_registered_only() {
   377                 response.add(
   385                 response.add(Bye(REGISTRATION_REQUIRED.to_string()).send_self());
   378                     Bye("This server only allows registered users to join.".to_string())
       
   379                         .send_self(),
       
   380                 );
       
   381                 response.remove_client(client_id);
   386                 response.remove_client(client_id);
   382             } else if is_registered {
   387             } else if is_registered {
   383                 let salt = server.anteroom.clients[client_id].server_salt.clone();
   388                 let salt = server.anteroom.clients[client_id].server_salt.clone();
   384                 response.add(AskPassword(salt).send_self());
   389                 response.add(AskPassword(salt).send_self());
   385             } else if let Some(client) = server.anteroom.remove_client(client_id) {
   390             } else if let Some(client) = server.anteroom.remove_client(client_id) {
   386                 server.add_client(client_id, client);
   391                 server.add_client(client_id, client);
   387                 common::join_lobby(server, response);
   392                 common::get_lobby_join_data(server, response);
   388             }
   393             }
   389         }
   394         }
   390         IoResult::Account(Some(info)) => {
   395         IoResult::Account(Some(info)) => {
   391             response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self());
   396             response.add(ServerAuth(format!("{:x}", info.server_hash)).send_self());
   392             if let Some(client) = server.anteroom.remove_client(client_id) {
   397             if let Some(mut client) = server.anteroom.remove_client(client_id) {
       
   398                 client.is_registered = info.is_registered;
       
   399                 client.is_admin = info.is_admin;
       
   400                 client.is_contributor = info.is_contributor;
   393                 server.add_client(client_id, client);
   401                 server.add_client(client_id, client);
   394                 let client = &mut server.clients[client_id];
   402                 common::get_lobby_join_data(server, response);
   395                 client.set_is_registered(info.is_registered);
       
   396                 client.set_is_admin(info.is_admin);
       
   397                 client.set_is_contributor(info.is_contributor);
       
   398                 common::join_lobby(server, response);
       
   399             }
   403             }
   400         }
   404         }
   401         IoResult::Account(None) => {
   405         IoResult::Account(None) => {
   402             response.add(Error("Authentication failed.".to_string()).send_self());
   406             response.error(AUTHENTICATION_FAILED);
   403             response.remove_client(client_id);
   407             response.remove_client(client_id);
   404         }
   408         }
   405         IoResult::Replay(Some(replay)) => {
   409         IoResult::Replay(Some(replay)) => {
   406             let protocol = server.clients[client_id].protocol_number;
   410             let client = server.client(client_id);
       
   411             let protocol = client.protocol_number;
   407             let start_msg = if protocol < 58 {
   412             let start_msg = if protocol < 58 {
   408                 RoomJoined(vec![server.clients[client_id].nick.clone()])
   413                 RoomJoined(vec![client.nick.clone()])
   409             } else {
   414             } else {
   410                 ReplayStart
   415                 ReplayStart
   411             };
   416             };
   412             response.add(start_msg.send_self());
   417             response.add(start_msg.send_self());
   413 
   418 
   419             if protocol < 58 {
   424             if protocol < 58 {
   420                 response.add(Kicked.send_self());
   425                 response.add(Kicked.send_self());
   421             }
   426             }
   422         }
   427         }
   423         IoResult::Replay(None) => {
   428         IoResult::Replay(None) => {
   424             response.add(Warning("Could't load the replay".to_string()).send_self())
   429             response.warn(REPLAY_LOAD_FAILED);
   425         }
   430         }
   426         IoResult::SaveRoom(_, true) => {
   431         IoResult::SaveRoom(_, true) => {
   427             response.add(server_chat("Room configs saved successfully.".to_string()).send_self());
   432             response.add(server_chat(ROOM_CONFIG_SAVED.to_string()).send_self());
   428         }
   433         }
   429         IoResult::SaveRoom(_, false) => {
   434         IoResult::SaveRoom(_, false) => {
   430             response.add(Warning("Unable to save the room configs.".to_string()).send_self());
   435             response.warn(ROOM_CONFIG_SAVE_FAILED);
   431         }
   436         }
   432         IoResult::LoadRoom(room_id, Some(contents)) => {
   437         IoResult::LoadRoom(room_id, Some(contents)) => {
   433             if let Some(ref mut room) = server.rooms.get_mut(room_id) {
   438             if let Some(ref mut room) = server.rooms.get_mut(room_id) {
   434                 match room.set_saves(&contents) {
   439                 match room.set_saves(&contents) {
   435                     Ok(_) => response.add(
   440                     Ok(_) => response.add(server_chat(ROOM_CONFIG_LOADED.to_string()).send_self()),
   436                         server_chat("Room configs loaded successfully.".to_string()).send_self(),
       
   437                     ),
       
   438                     Err(e) => {
   441                     Err(e) => {
   439                         warn!("Error while deserializing the room configs: {}", e);
   442                         warn!("Error while deserializing the room configs: {}", e);
   440                         response.add(
   443                         response.warn(ROOM_CONFIG_DESERIALIZE_FAILED);
   441                             Warning("Unable to deserialize the room configs.".to_string())
       
   442                                 .send_self(),
       
   443                         );
       
   444                     }
   444                     }
   445                 }
   445                 }
   446             }
   446             }
   447         }
   447         }
   448         IoResult::LoadRoom(_, None) => {
   448         IoResult::LoadRoom(_, None) => {
   449             response.add(Warning("Unable to load the room configs.".to_string()).send_self());
   449             response.warn(ROOM_CONFIG_LOAD_FAILED);
   450         }
   450         }
   451     }
   451     }
   452 }
   452 }
   453 
   453 
   454 #[cfg(test)]
   454 #[cfg(test)]