gameServer2/src/server/handlers/inroom.rs
changeset 13666 09f4a30e50cc
parent 13530 80db7232b4b5
child 13709 e335daaa77a9
equal deleted inserted replaced
13665:5664650befcd 13666:09f4a30e50cc
     1 use mio;
     1 use mio;
     2 
     2 
     3 use protocol::messages::{
     3 use crate::{
     4     HWProtocolMessage,
     4     server::{
     5     HWServerMessage::*,
     5         coretypes::{ClientId, RoomId, Voting, VoteType},
     6     server_chat
     6         server::HWServer,
       
     7         room::{HWRoom, RoomFlags},
       
     8         actions::{Action, Action::*}
       
     9     },
       
    10     protocol::messages::{
       
    11         HWProtocolMessage,
       
    12         HWServerMessage::*,
       
    13         server_chat
       
    14     },
       
    15     utils::is_name_illegal
     7 };
    16 };
     8 use server::{
       
     9     coretypes::{ClientId, RoomId, Voting, VoteType},
       
    10     server::HWServer,
       
    11     room::{HWRoom, RoomFlags},
       
    12     actions::{Action, Action::*}
       
    13 };
       
    14 use utils::is_name_illegal;
       
    15 use std::{
    17 use std::{
    16     mem::swap, fs::{File, OpenOptions},
    18     mem::swap, fs::{File, OpenOptions},
    17     io::{Read, Write, Result, Error, ErrorKind}
    19     io::{Read, Write, Result, Error, ErrorKind}
    18 };
    20 };
    19 use base64::{encode, decode};
    21 use base64::{encode, decode};
    56             },
    58             },
    57         _ => false
    59         _ => false
    58     }
    60     }
    59 }
    61 }
    60 
    62 
    61 fn is_msg_valid(msg: &[u8], team_indices: &[u8]) -> bool {
    63 fn is_msg_valid(msg: &[u8], _team_indices: &[u8]) -> bool {
    62     if let Some(typ) = msg.get(1) {
    64     if let Some(typ) = msg.get(1) {
    63         VALID_MESSAGES.contains(typ)
    65         VALID_MESSAGES.contains(typ)
    64     } else {
    66     } else {
    65         false
    67         false
    66     }
    68     }
    83         VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number)
    85         VoteType::HedgehogsPerTeam(number) => format!("hedgehogs per team: {}", number)
    84     })
    86     })
    85 }
    87 }
    86 
    88 
    87 fn room_message_flag(msg: &HWProtocolMessage) -> RoomFlags {
    89 fn room_message_flag(msg: &HWProtocolMessage) -> RoomFlags {
    88     use protocol::messages::HWProtocolMessage::*;
    90     use crate::protocol::messages::HWProtocolMessage::*;
    89     match msg {
    91     match msg {
    90         ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN,
    92         ToggleRestrictJoin => RoomFlags::RESTRICTED_JOIN,
    91         ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD,
    93         ToggleRestrictTeams => RoomFlags::RESTRICTED_TEAM_ADD,
    92         ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS,
    94         ToggleRegisteredOnly => RoomFlags::RESTRICTED_UNREGISTERED_PLAYERS,
    93         _ => RoomFlags::empty()
    95         _ => RoomFlags::empty()
   105     let mut writer = OpenOptions::new().create(true).write(true).open(filename)?;
   107     let mut writer = OpenOptions::new().create(true).write(true).open(filename)?;
   106     writer.write_all(content.as_bytes())
   108     writer.write_all(content.as_bytes())
   107 }
   109 }
   108 
   110 
   109 pub fn handle(server: &mut HWServer, client_id: ClientId, room_id: RoomId, message: HWProtocolMessage) {
   111 pub fn handle(server: &mut HWServer, client_id: ClientId, room_id: RoomId, message: HWProtocolMessage) {
   110     use protocol::messages::HWProtocolMessage::*;
   112     use crate::protocol::messages::HWProtocolMessage::*;
   111     match message {
   113     match message {
   112         Part(None) => server.react(client_id, vec![
   114         Part(None) => server.react(client_id, vec![
   113             MoveToLobby("part".to_string())]),
   115             MoveToLobby("part".to_string())]),
   114         Part(Some(msg)) => server.react(client_id, vec![
   116         Part(Some(msg)) => server.react(client_id, vec![
   115             MoveToLobby(format!("part: {}", msg))]),
   117             MoveToLobby(format!("part: {}", msg))]),
   152                     vec![SendRoomUpdate(Some(old_name))]
   154                     vec![SendRoomUpdate(Some(old_name))]
   153                 };
   155                 };
   154             server.react(client_id, actions);
   156             server.react(client_id, actions);
   155         },
   157         },
   156         ToggleReady => {
   158         ToggleReady => {
   157             let actions = if let (c, Some(r)) = server.client_and_room(client_id) {
   159             if let (c, Some(r)) = server.client_and_room(client_id) {
   158                 let flags = if c.is_ready() {
   160                 let flags = if c.is_ready() {
   159                     r.ready_players_number -= 1;
   161                     r.ready_players_number -= 1;
   160                     "-r"
   162                     "-r"
   161                 } else {
   163                 } else {
   162                     r.ready_players_number += 1;
   164                     r.ready_players_number += 1;
   163                     "+r"
   165                     "+r"
   164                 };
   166                 };
   165                 let is_ready = !c.is_ready();
   167                 c.set_is_ready(!c.is_ready());
   166                 c.set_is_ready(is_ready);
       
   167                 let mut v =
   168                 let mut v =
   168                     vec![ClientFlags(flags.to_string(), vec![c.nick.clone()])
   169                     vec![ClientFlags(flags.to_string(), vec![c.nick.clone()])
   169                         .send_all().in_room(r.id).action()];
   170                         .send_all().in_room(r.id).action()];
   170                 if r.is_fixed() && r.ready_players_number == r.players_number {
   171                 if r.is_fixed() && r.ready_players_number == r.players_number {
   171                     v.push(StartRoomGame(r.id))
   172                     v.push(StartRoomGame(r.id))
   172                 }
   173                 }
   173                 v
   174                 server.react(client_id, v);
   174             } else {
   175             }
   175                 Vec::new()
       
   176             };
       
   177             server.react(client_id, actions);
       
   178         }
   176         }
   179         AddTeam(info) => {
   177         AddTeam(info) => {
   180             let mut actions = Vec::new();
   178             let mut actions = Vec::new();
   181             if let (c, Some(r)) = server.client_and_room(client_id) {
   179             if let (c, Some(r)) = server.client_and_room(client_id) {
   182                 if r.teams.len() >= r.team_limit as usize {
   180                 if r.teams.len() >= r.team_limit as usize {
   222                 }
   220                 }
   223             };
   221             };
   224             server.react(client_id, actions);
   222             server.react(client_id, actions);
   225         },
   223         },
   226         SetHedgehogsNumber(team_name, number) => {
   224         SetHedgehogsNumber(team_name, number) => {
   227             let actions = if let (c, Some(r)) = server.client_and_room(client_id) {
   225             if let (c, Some(r)) = server.client_and_room(client_id) {
   228                 let addable_hedgehogs = r.addable_hedgehogs();
   226                 let addable_hedgehogs = r.addable_hedgehogs();
   229                 if let Some((_, mut team)) = r.find_team_and_owner_mut(|t| t.name == team_name) {
   227                 let actions = if let Some((_, team)) = r.find_team_and_owner_mut(|t| t.name == team_name) {
   230                     if !c.is_master() {
   228                     if !c.is_master() {
   231                         vec![ProtocolError("You're not the room master!".to_string())]
   229                         vec![ProtocolError("You're not the room master!".to_string())]
   232                     } else if number < 1 || number > 8
   230                     } else if number < 1 || number > 8
   233                            || number > addable_hedgehogs + team.hedgehogs_number {
   231                            || number > addable_hedgehogs + team.hedgehogs_number {
   234                         vec![HedgehogsNumber(team.name.clone(), team.hedgehogs_number)
   232                         vec![HedgehogsNumber(team.name.clone(), team.hedgehogs_number)
   238                         vec![HedgehogsNumber(team.name.clone(), number)
   236                         vec![HedgehogsNumber(team.name.clone(), number)
   239                             .send_all().in_room(room_id).but_self().action()]
   237                             .send_all().in_room(room_id).but_self().action()]
   240                     }
   238                     }
   241                 } else {
   239                 } else {
   242                     vec![(Warn("No such team.".to_string()))]
   240                     vec![(Warn("No such team.".to_string()))]
   243                 }
   241                 };
   244             } else {
   242                 server.react(client_id, actions);
   245                 Vec::new()
   243             }
   246             };
       
   247             server.react(client_id, actions);
       
   248         },
   244         },
   249         SetTeamColor(team_name, color) => {
   245         SetTeamColor(team_name, color) => {
   250             let mut owner_id = None;
   246             if let (c, Some(r)) = server.client_and_room(client_id) {
   251             let actions = if let (c, Some(r)) = server.client_and_room(client_id) {
   247                 let mut owner_id = None;
   252                 if let Some((owner, mut team)) = r.find_team_and_owner_mut(|t| t.name == team_name) {
   248                 let actions = if let Some((owner, team)) = r.find_team_and_owner_mut(|t| t.name == team_name) {
   253                     if !c.is_master() {
   249                     if !c.is_master() {
   254                         vec![ProtocolError("You're not the room master!".to_string())]
   250                         vec![ProtocolError("You're not the room master!".to_string())]
   255                     } else if false  {
   251                     } else if false  {
   256                         Vec::new()
   252                         Vec::new()
   257                     } else {
   253                     } else {
   260                         vec![TeamColor(team.name.clone(), color)
   256                         vec![TeamColor(team.name.clone(), color)
   261                             .send_all().in_room(room_id).but_self().action()]
   257                             .send_all().in_room(room_id).but_self().action()]
   262                     }
   258                     }
   263                 } else {
   259                 } else {
   264                     vec![(Warn("No such team.".to_string()))]
   260                     vec![(Warn("No such team.".to_string()))]
   265                 }
   261                 };
   266             } else {
   262 
   267                 Vec::new()
   263                 if let Some(id) = owner_id {
   268             };
   264                     server.clients[id].clan = Some(color);
   269 
   265                 }
   270             if let Some(id) = owner_id {
   266 
   271                 server.clients[id].clan = Some(color);
   267                 server.react(client_id, actions);
   272             }
   268             };
   273 
       
   274             server.react(client_id, actions);
       
   275         },
   269         },
   276         Cfg(cfg) => {
   270         Cfg(cfg) => {
   277             let actions = if let (c, Some(r)) = server.client_and_room(client_id) {
   271             if let (c, Some(r)) = server.client_and_room(client_id) {
   278                 if r.is_fixed() {
   272                 let actions = if r.is_fixed() {
   279                     vec![Warn("Access denied.".to_string())]
   273                     vec![Warn("Access denied.".to_string())]
   280                 } else if !c.is_master() {
   274                 } else if !c.is_master() {
   281                     vec![ProtocolError("You're not the room master!".to_string())]
   275                     vec![ProtocolError("You're not the room master!".to_string())]
   282                 } else {
   276                 } else {
   283                     let v = vec![cfg.to_server_msg()
   277                     let v = vec![cfg.to_server_msg()
   284                         .send_all().in_room(r.id).but_self().action()];
   278                         .send_all().in_room(r.id).but_self().action()];
   285                     r.set_config(cfg);
   279                     r.set_config(cfg);
   286                     v
   280                     v
   287                 }
   281                 };
   288             } else {
   282                 server.react(client_id, actions);
   289                 Vec::new()
   283             }
   290             };
       
   291             server.react(client_id, actions);
       
   292         }
   284         }
   293         Save(name, location) => {
   285         Save(name, location) => {
   294             let actions = vec![server_chat(format!("Room config saved as {}", name))
   286             let actions = vec![server_chat(format!("Room config saved as {}", name))
   295                 .send_all().in_room(room_id).action()];
   287                 .send_all().in_room(room_id).action()];
   296             server.rooms[room_id].save_config(name, location);
   288             server.rooms[room_id].save_config(name, location);
   297             server.react(client_id, actions);
   289             server.react(client_id, actions);
   298         }
   290         }
   299         SaveRoom(filename) => {
   291         SaveRoom(filename) => {
   300             let actions = if server.clients[client_id].is_admin() {
   292             if server.clients[client_id].is_admin() {
   301                 match server.rooms[room_id].get_saves() {
   293                 let actions = match server.rooms[room_id].get_saves() {
   302                     Ok(text) => match write_file(&filename, &text) {
   294                     Ok(text) => match write_file(&filename, &text) {
   303                         Ok(_) => vec![server_chat("Room configs saved successfully.".to_string())
   295                         Ok(_) => vec![server_chat("Room configs saved successfully.".to_string())
   304                             .send_self().action()],
   296                             .send_self().action()],
   305                         Err(e) => {
   297                         Err(e) => {
   306                             warn!("Error while writing the config file \"{}\": {}", filename, e);
   298                             warn!("Error while writing the config file \"{}\": {}", filename, e);
   309                     }
   301                     }
   310                     Err(e) => {
   302                     Err(e) => {
   311                         warn!("Error while serializing the room configs: {}", e);
   303                         warn!("Error while serializing the room configs: {}", e);
   312                         vec![Warn("Unable to serialize the room configs.".to_string())]
   304                         vec![Warn("Unable to serialize the room configs.".to_string())]
   313                     }
   305                     }
   314                 }
   306                 };
   315             } else {
   307                 server.react(client_id, actions);
   316                 Vec::new()
   308             }
   317             };
       
   318             server.react(client_id, actions);
       
   319         }
   309         }
   320         LoadRoom(filename) => {
   310         LoadRoom(filename) => {
   321             let actions = if server.clients[client_id].is_admin() {
   311             if server.clients[client_id].is_admin() {
   322                 match read_file(&filename) {
   312                 let actions = match read_file(&filename) {
   323                     Ok(text) => match server.rooms[room_id].set_saves(&text) {
   313                     Ok(text) => match server.rooms[room_id].set_saves(&text) {
   324                         Ok(_) => vec![server_chat("Room configs loaded successfully.".to_string())
   314                         Ok(_) => vec![server_chat("Room configs loaded successfully.".to_string())
   325                             .send_self().action()],
   315                             .send_self().action()],
   326                         Err(e) => {
   316                         Err(e) => {
   327                             warn!("Error while deserializing the room configs: {}", e);
   317                             warn!("Error while deserializing the room configs: {}", e);
   330                     }
   320                     }
   331                     Err(e) => {
   321                     Err(e) => {
   332                         warn!("Error while reading the config file \"{}\": {}", filename, e);
   322                         warn!("Error while reading the config file \"{}\": {}", filename, e);
   333                         vec![Warn("Unable to load the room configs.".to_string())]
   323                         vec![Warn("Unable to load the room configs.".to_string())]
   334                     }
   324                     }
   335                 }
   325                 };
   336             } else {
   326                 server.react(client_id, actions);
   337                 Vec::new()
   327             }
   338             };
       
   339             server.react(client_id, actions);
       
   340         }
   328         }
   341         Delete(name) => {
   329         Delete(name) => {
   342             let actions = if !server.rooms[room_id].delete_config(&name) {
   330             let actions = if !server.rooms[room_id].delete_config(&name) {
   343                 vec![Warn(format!("Save doesn't exist: {}", name))]
   331                 vec![Warn(format!("Save doesn't exist: {}", name))]
   344             } else {
   332             } else {