gameServer2/src/server/actions.rs
changeset 13666 09f4a30e50cc
parent 13521 e3ae9eea0689
child 13775 5fb40c8e5542
equal deleted inserted replaced
13665:5664650befcd 13666:09f4a30e50cc
     9     client::HWClient,
     9     client::HWClient,
    10     coretypes::{ClientId, RoomId, GameCfg, VoteType},
    10     coretypes::{ClientId, RoomId, GameCfg, VoteType},
    11     room::HWRoom,
    11     room::HWRoom,
    12     handlers
    12     handlers
    13 };
    13 };
    14 use protocol::messages::{
    14 use crate::{
    15     HWProtocolMessage,
    15     protocol::messages::{
    16     HWServerMessage,
    16         HWProtocolMessage,
    17     HWServerMessage::*,
    17         HWServerMessage,
    18     server_chat
    18         HWServerMessage::*,
       
    19         server_chat
       
    20     },
       
    21     utils::to_engine_msg
    19 };
    22 };
    20 use utils::to_engine_msg;
       
    21 use rand::{thread_rng, Rng, distributions::Uniform};
    23 use rand::{thread_rng, Rng, distributions::Uniform};
    22 
    24 
    23 pub enum Destination {
    25 pub enum Destination {
    24     ToId(ClientId),
    26     ToId(ClientId),
    25     ToSelf,
    27     ToSelf,
   116 
   118 
   117 pub fn run_action(server: &mut HWServer, client_id: usize, action: Action) {
   119 pub fn run_action(server: &mut HWServer, client_id: usize, action: Action) {
   118     match action {
   120     match action {
   119         Send(msg) => server.send(client_id, &msg.destination, msg.message),
   121         Send(msg) => server.send(client_id, &msg.destination, msg.message),
   120         ByeClient(msg) => {
   122         ByeClient(msg) => {
   121             let room_id;
   123             let c = &server.clients[client_id];
   122             let nick;
   124             let nick = c.nick.clone();
   123             {
   125 
   124                 let c = &server.clients[client_id];
   126             if let Some(id) = c.room_id{
   125                 room_id = c.room_id;
       
   126                 nick = c.nick.clone();
       
   127             }
       
   128 
       
   129             if let Some(id) = room_id{
       
   130                 if id != server.lobby_id {
   127                 if id != server.lobby_id {
   131                     server.react(client_id, vec![
   128                     server.react(client_id, vec![
   132                         MoveToLobby(format!("quit: {}", msg.clone()))]);
   129                         MoveToLobby(format!("quit: {}", msg.clone()))]);
   133                 }
   130                 }
   134             }
   131             }
   153                     ]);
   150                     ]);
   154             },
   151             },
   155         JoinLobby => {
   152         JoinLobby => {
   156             server.clients[client_id].room_id = Some(server.lobby_id);
   153             server.clients[client_id].room_id = Some(server.lobby_id);
   157 
   154 
   158             let joined_msg;
   155             let mut lobby_nicks = Vec::new();
   159             {
   156             for (_, c) in server.clients.iter() {
   160                 let mut lobby_nicks = Vec::new();
   157                 if c.room_id.is_some() {
   161                 for (_, c) in server.clients.iter() {
   158                     lobby_nicks.push(c.nick.clone());
   162                     if c.room_id.is_some() {
   159                 }
   163                         lobby_nicks.push(c.nick.clone());
   160             }
   164                     }
   161             let joined_msg = LobbyJoined(lobby_nicks);
   165                 }
   162 
   166                 joined_msg = LobbyJoined(lobby_nicks);
       
   167             }
       
   168             let everyone_msg = LobbyJoined(vec![server.clients[client_id].nick.clone()]);
   163             let everyone_msg = LobbyJoined(vec![server.clients[client_id].nick.clone()]);
   169             let flags_msg = ClientFlags(
   164             let flags_msg = ClientFlags(
   170                 "+i".to_string(),
   165                 "+i".to_string(),
   171                 server.clients.iter()
   166                 server.clients.iter()
   172                     .filter(|(_, c)| c.room_id.is_some())
   167                     .filter(|(_, c)| c.room_id.is_some())
   186                 rooms_msg.send_self().action(),
   181                 rooms_msg.send_self().action(),
   187                 ]);
   182                 ]);
   188         },
   183         },
   189         AddRoom(name, password) => {
   184         AddRoom(name, password) => {
   190             let room_id = server.add_room();;
   185             let room_id = server.add_room();;
   191             let actions = {
   186 
   192                 let r = &mut server.rooms[room_id];
   187             let r = &mut server.rooms[room_id];
   193                 let c = &mut server.clients[client_id];
   188             let c = &mut server.clients[client_id];
   194                 r.master_id = Some(c.id);
   189             r.master_id = Some(c.id);
   195                 r.name = name;
   190             r.name = name;
   196                 r.password = password;
   191             r.password = password;
   197                 r.protocol_number = c.protocol_number;
   192             r.protocol_number = c.protocol_number;
   198 
   193 
   199                 vec![
   194             let actions = vec![
   200                     RoomAdd(r.info(Some(&c))).send_all()
   195                 RoomAdd(r.info(Some(&c))).send_all()
   201                         .with_protocol(r.protocol_number).action(),
   196                     .with_protocol(r.protocol_number).action(),
   202                     MoveToRoom(room_id)]
   197                 MoveToRoom(room_id)];
   203             };
   198 
   204             server.react(client_id, actions);
   199             server.react(client_id, actions);
   205         },
   200         },
   206         RemoveRoom(room_id) => {
   201         RemoveRoom(room_id) => {
   207             let actions = {
   202             let r = &mut server.rooms[room_id];
   208                 let r = &mut server.rooms[room_id];
   203             let actions = vec![RoomRemove(r.name.clone()).send_all()
   209                 vec![RoomRemove(r.name.clone()).send_all()
   204                 .with_protocol(r.protocol_number).action()];
   210                         .with_protocol(r.protocol_number).action()]
       
   211             };
       
   212             server.rooms.remove(room_id);
   205             server.rooms.remove(room_id);
   213             server.react(client_id, actions);
   206             server.react(client_id, actions);
   214         }
   207         }
   215         MoveToRoom(room_id) => {
   208         MoveToRoom(room_id) => {
   216             let actions = {
   209             let r = &mut server.rooms[room_id];
   217                 let r = &mut server.rooms[room_id];
   210             let c = &mut server.clients[client_id];
   218                 let c = &mut server.clients[client_id];
   211             r.players_number += 1;
   219                 r.players_number += 1;
   212             c.room_id = Some(room_id);
   220                 c.room_id = Some(room_id);
   213 
   221 
   214             let is_master = r.master_id == Some(c.id);
   222                 let is_master = r.master_id == Some(c.id);
   215             c.set_is_master(is_master);
   223                 c.set_is_master(is_master);
   216             c.set_is_ready(is_master);
   224                 c.set_is_ready(is_master);
   217             c.set_is_joined_mid_game(false);
   225                 c.set_is_joined_mid_game(false);
   218 
   226 
   219             if is_master {
   227                 if is_master {
   220                 r.ready_players_number += 1;
   228                     r.ready_players_number += 1;
   221             }
   229                 }
   222 
   230 
   223             let mut v = vec![
   231                 let mut v = vec![
   224                 RoomJoined(vec![c.nick.clone()]).send_all().in_room(room_id).action(),
   232                     RoomJoined(vec![c.nick.clone()]).send_all().in_room(room_id).action(),
   225                 ClientFlags("+i".to_string(), vec![c.nick.clone()]).send_all().action(),
   233                     ClientFlags("+i".to_string(), vec![c.nick.clone()]).send_all().action(),
   226                 SendRoomUpdate(None)];
   234                     SendRoomUpdate(None)];
   227 
   235                 if !r.greeting.is_empty() {
   228             if !r.greeting.is_empty() {
   236                     v.push(ChatMsg {nick: "[greeting]".to_string(), msg: r.greeting.clone()}
   229                 v.push(ChatMsg {nick: "[greeting]".to_string(), msg: r.greeting.clone()}
       
   230                     .send_self().action());
       
   231             }
       
   232 
       
   233             if !c.is_master() {
       
   234                 let team_names: Vec<_>;
       
   235                 if let Some(ref mut info) = r.game_info {
       
   236                     c.set_is_in_game(true);
       
   237                     c.set_is_joined_mid_game(true);
       
   238 
       
   239                     {
       
   240                         let teams = info.client_teams(c.id);
       
   241                         c.teams_in_game = teams.clone().count() as u8;
       
   242                         c.clan = teams.clone().next().map(|t| t.color);
       
   243                         team_names = teams.map(|t| t.name.clone()).collect();
       
   244                     }
       
   245 
       
   246                     if !team_names.is_empty() {
       
   247                         info.left_teams.retain(|name|
       
   248                             !team_names.contains(&name));
       
   249                         info.teams_in_game += team_names.len() as u8;
       
   250                         r.teams = info.teams_at_start.iter()
       
   251                             .filter(|(_, t)| !team_names.contains(&t.name))
       
   252                             .cloned().collect();
       
   253                     }
       
   254                 } else {
       
   255                     team_names = Vec::new();
       
   256                 }
       
   257 
       
   258                 v.push(SendRoomData{ to: client_id, teams: true, config: true, flags: true});
       
   259 
       
   260                 if let Some(ref info) = r.game_info {
       
   261                     v.push(RunGame.send_self().action());
       
   262                     v.push(ClientFlags("+g".to_string(), vec![c.nick.clone()])
       
   263                         .send_all().in_room(r.id).action());
       
   264                     v.push(ForwardEngineMessage(
       
   265                         vec![to_engine_msg("e$spectate 1".bytes())])
   237                         .send_self().action());
   266                         .send_self().action());
   238                 }
   267                     v.push(ForwardEngineMessage(info.msg_log.clone())
   239                 if !c.is_master() {
   268                         .send_self().action());
   240                     let team_names: Vec<_>;
   269 
   241                     if let Some(ref mut info) = r.game_info {
   270                     for name in &team_names {
   242                         c.set_is_in_game(true);
   271                         v.push(ForwardEngineMessage(
   243                         c.set_is_joined_mid_game(true);
   272                             vec![to_engine_msg(once(b'G').chain(name.bytes()))])
   244 
       
   245                         {
       
   246                             let teams = info.client_teams(c.id);
       
   247                             c.teams_in_game = teams.clone().count() as u8;
       
   248                             c.clan = teams.clone().next().map(|t| t.color);
       
   249                             team_names = teams.map(|t| t.name.clone()).collect();
       
   250                         }
       
   251 
       
   252                         if !team_names.is_empty() {
       
   253                             info.left_teams.retain(|name|
       
   254                                 !team_names.contains(&name));
       
   255                             info.teams_in_game += team_names.len() as u8;
       
   256                             r.teams = info.teams_at_start.iter()
       
   257                                 .filter(|(_, t)| !team_names.contains(&t.name))
       
   258                                 .cloned().collect();
       
   259                         }
       
   260                     } else {
       
   261                         team_names = Vec::new();
       
   262                     }
       
   263 
       
   264                     v.push(SendRoomData{ to: client_id, teams: true, config: true, flags: true});
       
   265 
       
   266                     if let Some(ref info) = r.game_info {
       
   267                         v.push(RunGame.send_self().action());
       
   268                         v.push(ClientFlags("+g".to_string(), vec![c.nick.clone()])
       
   269                             .send_all().in_room(r.id).action());
   273                             .send_all().in_room(r.id).action());
   270                         v.push(ForwardEngineMessage(
   274                     }
   271                             vec![to_engine_msg("e$spectate 1".bytes())])
   275                     if info.is_paused {
   272                             .send_self().action());
   276                         v.push(ForwardEngineMessage(vec![to_engine_msg(once(b'I'))])
   273                         v.push(ForwardEngineMessage(info.msg_log.clone())
   277                             .send_all().in_room(r.id).action())
   274                             .send_self().action());
   278                     }
   275 
   279                 }
   276                         for name in &team_names {
   280             }
   277                             v.push(ForwardEngineMessage(
   281             server.react(client_id, v);
   278                                 vec![to_engine_msg(once(b'G').chain(name.bytes()))])
       
   279                                 .send_all().in_room(r.id).action());
       
   280                         }
       
   281                         if info.is_paused {
       
   282                             v.push(ForwardEngineMessage(vec![to_engine_msg(once(b'I'))])
       
   283                                 .send_all().in_room(r.id).action())
       
   284                         }
       
   285                     }
       
   286                 }
       
   287                 v
       
   288             };
       
   289             server.react(client_id, actions);
       
   290         }
   282         }
   291         SendRoomData {to, teams, config, flags} => {
   283         SendRoomData {to, teams, config, flags} => {
   292             let mut actions = Vec::new();
   284             let mut actions = Vec::new();
   293             let room_id = server.clients[client_id].room_id;
   285             let room_id = server.clients[client_id].room_id;
   294             if let Some(r) = room_id.and_then(|id| server.rooms.get(id)) {
   286             if let Some(r) = room_id.and_then(|id| server.rooms.get(id)) {
   481                 if let Some(nick) = new_nick {
   473                 if let Some(nick) = new_nick {
   482                     actions.push(ClientFlags("+h".to_string(), vec![nick])
   474                     actions.push(ClientFlags("+h".to_string(), vec![nick])
   483                         .send_all().in_room(r.id).action());
   475                         .send_all().in_room(r.id).action());
   484                 }
   476                 }
   485             }
   477             }
   486             if let Some(id) = new_id { server.clients[id].set_is_master(true) }
   478             if let Some(id) = new_id {
       
   479                 server.clients[id].set_is_master(true)
       
   480             }
   487             server.react(client_id, actions);
   481             server.react(client_id, actions);
   488         }
   482         }
   489         RemoveTeam(name) => {
   483         RemoveTeam(name) => {
   490             let mut actions = Vec::new();
   484             let mut actions = Vec::new();
   491             if let (c, Some(r)) = server.client_and_room(client_id) {
   485             if let (c, Some(r)) = server.client_and_room(client_id) {
   500                 }
   494                 }
   501             }
   495             }
   502             server.react(client_id, actions);
   496             server.react(client_id, actions);
   503         },
   497         },
   504         RemoveClientTeams => {
   498         RemoveClientTeams => {
   505             let actions = if let (c, Some(r)) = server.client_and_room(client_id) {
   499             if let (c, Some(r)) = server.client_and_room(client_id) {
   506                 r.client_teams(c.id).map(|t| RemoveTeam(t.name.clone())).collect()
   500                 let actions = r.client_teams(c.id).map(|t| RemoveTeam(t.name.clone())).collect();
   507             } else {
   501                 server.react(client_id, actions);
   508                 Vec::new()
   502             }
   509             };
       
   510             server.react(client_id, actions);
       
   511         }
   503         }
   512         SendRoomUpdate(old_name) => {
   504         SendRoomUpdate(old_name) => {
   513             let actions = if let (c, Some(r)) = server.client_and_room(client_id) {
   505             if let (c, Some(r)) = server.client_and_room(client_id) {
   514                 let name = old_name.unwrap_or_else(|| r.name.clone());
   506                 let name = old_name.unwrap_or_else(|| r.name.clone());
   515                 vec![RoomUpdated(name, r.info(Some(&c)))
   507                 let actions = vec![RoomUpdated(name, r.info(Some(&c)))
   516                     .send_all().with_protocol(r.protocol_number).action()]
   508                     .send_all().with_protocol(r.protocol_number).action()];
   517             } else {
   509                 server.react(client_id, actions);
   518                 Vec::new()
   510             }
   519             };
       
   520             server.react(client_id, actions);
       
   521         },
   511         },
   522         StartRoomGame(room_id) => {
   512         StartRoomGame(room_id) => {
   523             let actions = {
   513             let actions = {
   524                 let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server.clients.iter()
   514                 let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server.clients.iter()
   525                     .map(|(id, c)| (id, c.nick.clone())).unzip();
   515                     .map(|(id, c)| (id, c.nick.clone())).unzip();
   596             }
   586             }
   597 
   587 
   598             let nicks: Vec<_> = server.clients.iter_mut()
   588             let nicks: Vec<_> = server.clients.iter_mut()
   599                 .filter(|(_, c)| c.room_id == Some(room_id))
   589                 .filter(|(_, c)| c.room_id == Some(room_id))
   600                 .map(|(_, c)| {
   590                 .map(|(_, c)| {
   601                     let is_master = c.is_master();
   591                     c.set_is_ready(c.is_master());
   602                     c.set_is_ready(is_master);
       
   603                     c.set_is_joined_mid_game(false);
   592                     c.set_is_joined_mid_game(false);
   604                     c
   593                     c
   605                 }).filter_map(|c| if !c.is_master() {
   594                 }).filter_map(|c| if !c.is_master() {
   606                     Some(c.nick.clone())
   595                     Some(c.nick.clone())
   607                 } else {
   596                 } else {