rust/hedgewars-server/src/handlers/inroom.rs
changeset 15519 b3157d218ae2
parent 15518 e705d30e0f10
child 15522 4a0b06b03199
equal deleted inserted replaced
15518:e705d30e0f10 15519:b3157d218ae2
     1 use super::{common::rnd_reply, strings::*};
     1 use super::{common::rnd_reply, strings::*};
       
     2 use crate::core::room::GameInfo;
       
     3 use crate::core::server::AddTeamError;
     2 use crate::{
     4 use crate::{
     3     core::{
     5     core::{
     4         room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM},
     6         room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM},
     5         server::{
     7         server::{
     6             ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, ModifyTeamError,
     8             ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, ModifyTeamError,
   204             if room.is_fixed() && room.ready_players_number == room.players_number {
   206             if room.is_fixed() && room.ready_players_number == room.players_number {
   205                 let result = server.start_game(room_id);
   207                 let result = server.start_game(room_id);
   206                 super::common::get_start_game_data(server, room_id, result, response);
   208                 super::common::get_start_game_data(server, room_id, result, response);
   207             }
   209             }
   208         }
   210         }
   209         AddTeam(mut info) => {
   211         AddTeam(info) => {
   210             if room.teams.len() >= room.max_teams as usize {
   212             use crate::core::server::AddTeamError;
   211                 response.warn("Too many teams!");
   213             match server.add_team(client_id, info) {
   212             } else if room.addable_hedgehogs() == 0 {
   214                 Ok(team) => {
   213                 response.warn("Too many hedgehogs!");
   215                     response.add(TeamAccepted(team.name.clone()).send_self());
   214             } else if room.find_team(|t| t.name == info.name) != None {
   216                     response.add(
   215                 response.warn("There's already a team with same name in the list.");
   217                         TeamAdd(team.to_protocol())
   216             } else if room.game_info.is_some() {
   218                             .send_all()
   217                 response.warn("Joining not possible: Round is in progress.");
   219                             .in_room(room_id)
   218             } else if room.is_team_add_restricted() {
   220                             .but_self(),
   219                 response.warn("This room currently does not allow adding new teams.");
   221                     );
   220             } else {
   222                     response.add(
   221                 info.owner = client.nick.clone();
   223                         TeamColor(team.name.clone(), team.color)
   222                 let team = room.add_team(client.id, *info, client.protocol_number < 42);
   224                             .send_all()
   223                 client.teams_in_game += 1;
   225                             .in_room(room_id),
   224                 client.clan = Some(team.color);
   226                     );
   225                 response.add(TeamAccepted(team.name.clone()).send_self());
   227                     response.add(
   226                 response.add(
   228                         HedgehogsNumber(team.name.clone(), team.hedgehogs_number)
   227                     TeamAdd(team.to_protocol())
   229                             .send_all()
   228                         .send_all()
   230                             .in_room(room_id),
   229                         .in_room(room_id)
   231                     );
   230                         .but_self(),
   232 
   231                 );
   233                     let room = server.room(room_id);
   232                 response.add(
   234                     let room_master = if let Some(id) = room.master_id {
   233                     TeamColor(team.name.clone(), team.color)
   235                         Some(server.client(id))
   234                         .send_all()
   236                     } else {
   235                         .in_room(room_id),
   237                         None
   236                 );
   238                     };
   237                 response.add(
   239                     super::common::get_room_update(None, room, room_master, response);
   238                     HedgehogsNumber(team.name.clone(), team.hedgehogs_number)
   240                 }
   239                         .send_all()
   241                 Err(AddTeamError::TooManyTeams) => response.warn(TOO_MANY_TEAMS),
   240                         .in_room(room_id),
   242                 Err(AddTeamError::TooManyHedgehogs) => response.warn(TOO_MANY_HEDGEHOGS),
   241                 );
   243                 Err(AddTeamError::TeamAlreadyExists) => response.warn(TEAM_EXISTS),
   242 
   244                 Err(AddTeamError::GameInProgress) => response.warn(ROUND_IN_PROGRESS),
   243                 let room = server.room(room_id);
   245                 Err(AddTeamError::Restricted) => response.warn(TEAM_ADD_RESTRICTED),
   244                 let room_master = if let Some(id) = room.master_id {
   246             }
   245                     Some(server.client(id))
   247         }
   246                 } else {
   248         RemoveTeam(name) => {
   247                     None
   249             use crate::core::server::RemoveTeamError;
   248                 };
   250             match server.remove_team(client_id, &name) {
   249                 super::common::get_room_update(None, room, room_master, response);
   251                 Ok(()) => {
   250             }
   252                     let (client, room) = server.client_and_room(client_id, room_id);
   251         }
   253 
   252         RemoveTeam(name) => match room.find_team_owner(&name) {
   254                     let removed_teams = vec![name];
   253             None => response.warn("Error: The team you tried to remove does not exist."),
   255                     super::common::get_remove_teams_data(
   254             Some((id, _)) if id != client_id => {
   256                         room_id,
   255                 response.warn("You can't remove a team you don't own.")
   257                         client.is_in_game(),
   256             }
   258                         removed_teams,
   257             Some((_, name)) => {
   259                         response,
   258                 let name = name.to_string();
   260                     );
   259                 client.teams_in_game -= 1;
   261 
   260                 client.clan = room.find_team_color(client.id);
   262                     match room.game_info {
   261                 room.remove_team(&name);
   263                         Some(ref info) if info.teams_in_game == 0 => {
   262                 let removed_teams = vec![name];
   264                             let result = server.end_game(room_id);
   263                 super::common::get_remove_teams_data(
   265                             super::common::get_end_game_result(server, room_id, result, response);
   264                     room_id,
   266                         }
   265                     client.is_in_game(),
   267                         _ => (),
   266                     removed_teams,
   268                     }
   267                     response,
   269                 }
   268                 );
   270                 Err(RemoveTeamError::NoTeam) => response.warn(NO_TEAM_TO_REMOVE),
   269 
   271                 Err(RemoveTeamError::TeamNotOwned) => response.warn(TEAM_NOT_OWNED),
   270                 match room.game_info {
   272             }
   271                     Some(ref info) if info.teams_in_game == 0 => {
   273         }
   272                         let result = server.end_game(room_id);
       
   273                         super::common::get_end_game_result(server, room_id, result, response);
       
   274                     }
       
   275                     _ => (),
       
   276                 }
       
   277             }
       
   278         },
       
   279         SetHedgehogsNumber(team_name, number) => {
   274         SetHedgehogsNumber(team_name, number) => {
   280             let addable_hedgehogs = room.addable_hedgehogs();
   275             let addable_hedgehogs = room.addable_hedgehogs();
   281             if let Some((_, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) {
   276             if let Some((_, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) {
   282                 let max_hedgehogs = min(
   277                 let max_hedgehogs = min(
   283                     MAX_HEDGEHOGS_PER_TEAM,
   278                     MAX_HEDGEHOGS_PER_TEAM,
   508                     }
   503                     }
   509                 }
   504                 }
   510             }
   505             }
   511         }
   506         }
   512         RoundFinished => {
   507         RoundFinished => {
   513             let mut game_ended = false;
   508             if let Some(team_names) = server.leave_game(client_id) {
   514             if client.is_in_game() {
   509                 let (client, room) = server.client_and_room(client_id, room_id);
   515                 client.set_is_in_game(false);
       
   516                 response.add(
   510                 response.add(
   517                     ClientFlags(remove_flags(&[Flags::InGame]), vec![client.nick.clone()])
   511                     ClientFlags(remove_flags(&[Flags::InGame]), vec![client.nick.clone()])
   518                         .send_all()
   512                         .send_all()
   519                         .in_room(room.id),
   513                         .in_room(room.id),
   520                 );
   514                 );
   521                 let team_names: Vec<_> = room
   515 
   522                     .client_teams(client_id)
   516                 for team_name in team_names {
   523                     .map(|t| t.name.clone())
   517                     let msg = once(b'F').chain(team_name.bytes());
   524                     .collect();
   518                     response.add(
   525 
   519                         ForwardEngineMessage(vec![to_engine_msg(msg)])
   526                 if let Some(ref mut info) = room.game_info {
   520                             .send_all()
   527                     info.teams_in_game -= team_names.len() as u8;
   521                             .in_room(room_id)
   528                     if info.teams_in_game == 0 {
   522                             .but_self(),
   529                         game_ended = true;
   523                     );
   530                     }
   524                 }
   531 
   525 
   532                     for team_name in team_names {
   526                 if let Some(GameInfo {
   533                         let msg = once(b'F').chain(team_name.bytes());
   527                     teams_in_game: 0, ..
   534                         response.add(
   528                 }) = room.game_info
   535                             ForwardEngineMessage(vec![to_engine_msg(msg)])
   529                 {
   536                                 .send_all()
   530                     let result = server.end_game(room_id);
   537                                 .in_room(room_id)
   531                     super::common::get_end_game_result(server, room_id, result, response);
   538                                 .but_self(),
   532                 }
   539                         );
       
   540 
       
   541                         let remove_msg = to_engine_msg(once(b'F').chain(team_name.bytes()));
       
   542                         if let Some(m) = &info.sync_msg {
       
   543                             info.msg_log.push(m.clone());
       
   544                         }
       
   545                         if info.sync_msg.is_some() {
       
   546                             info.sync_msg = None
       
   547                         }
       
   548                         info.msg_log.push(remove_msg.clone());
       
   549                         response.add(
       
   550                             ForwardEngineMessage(vec![remove_msg])
       
   551                                 .send_all()
       
   552                                 .in_room(room_id)
       
   553                                 .but_self(),
       
   554                         );
       
   555                     }
       
   556                 }
       
   557             }
       
   558             if game_ended {
       
   559                 let result = server.end_game(room_id);
       
   560                 super::common::get_end_game_result(server, room_id, result, response);
       
   561             }
   533             }
   562         }
   534         }
   563         Rnd(v) => {
   535         Rnd(v) => {
   564             let result = rnd_reply(&v);
   536             let result = rnd_reply(&v);
   565             let mut echo = vec!["/rnd".to_string()];
   537             let mut echo = vec!["/rnd".to_string()];