1 use crate::{ |
1 use crate::{ |
2 core::{ |
2 core::{ |
3 client::HwClient, |
3 client::HwClient, |
4 room::HwRoom, |
4 room::HwRoom, |
5 server::{HwServer, JoinRoomError, LeaveRoomResult}, |
5 server::{HwServer, JoinRoomError, LeaveRoomError, LeaveRoomResult, StartGameError}, |
6 types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType}, |
6 types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType}, |
7 }, |
7 }, |
8 protocol::messages::{ |
8 protocol::messages::{ |
9 add_flags, remove_flags, server_chat, |
9 add_flags, remove_flags, server_chat, |
10 HwProtocolMessage::{self, Rnd}, |
10 HwProtocolMessage::{self, Rnd}, |
74 let rooms_msg = Rooms( |
74 let rooms_msg = Rooms( |
75 server |
75 server |
76 .rooms |
76 .rooms |
77 .iter() |
77 .iter() |
78 .filter(|(_, r)| r.protocol_number == client.protocol_number) |
78 .filter(|(_, r)| r.protocol_number == client.protocol_number) |
79 .flat_map(|(_, r)| r.info(r.master_id.map(|id| &server.clients[id]))) |
79 .flat_map(|(_, r)| r.info(r.master_id.map(|id| server.client(id)))) |
80 .collect(), |
80 .collect(), |
81 ); |
81 ); |
82 |
82 |
83 response.add(LobbyJoined(nick).send_all().but_self()); |
83 response.add(LobbyJoined(nick).send_all().but_self()); |
84 response.add( |
84 response.add( |
192 for team_name in removed_teams { |
192 for team_name in removed_teams { |
193 response.add(TeamRemove(team_name).send_all().in_room(room_id)); |
193 response.add(TeamRemove(team_name).send_all().in_room(room_id)); |
194 } |
194 } |
195 } |
195 } |
196 |
196 |
197 pub fn get_room_leave_data( |
197 pub fn get_room_leave_result( |
198 server: &HwServer, |
198 server: &HwServer, |
199 room: &HwRoom, |
199 room: &HwRoom, |
200 leave_message: &str, |
200 leave_message: &str, |
201 result: LeaveRoomResult, |
201 result: LeaveRoomResult, |
202 response: &mut Response, |
202 response: &mut Response, |
258 ); |
258 ); |
259 } |
259 } |
260 } |
260 } |
261 } |
261 } |
262 |
262 |
|
263 pub fn get_room_leave_data( |
|
264 server: &HwServer, |
|
265 room_id: RoomId, |
|
266 leave_message: &str, |
|
267 result: Result<LeaveRoomResult, LeaveRoomError>, |
|
268 response: &mut Response, |
|
269 ) { |
|
270 match result { |
|
271 Ok(result) => { |
|
272 let room = server.room(room_id); |
|
273 get_room_leave_result(server, room, leave_message, result, response) |
|
274 } |
|
275 Err(_) => (), |
|
276 } |
|
277 } |
|
278 |
263 pub fn remove_client(server: &mut HwServer, response: &mut Response, msg: String) { |
279 pub fn remove_client(server: &mut HwServer, response: &mut Response, msg: String) { |
264 let client_id = response.client_id(); |
280 let client_id = response.client_id(); |
265 let client = server.client(client_id); |
281 let client = server.client(client_id); |
266 let nick = client.nick.clone(); |
282 let nick = client.nick.clone(); |
267 |
283 |
268 if let Some(room_id) = client.room_id { |
284 if let Some(room_id) = client.room_id { |
269 match server.leave_room(client_id) { |
285 let result = server.leave_room(client_id); |
270 Ok(result) => { |
286 get_room_leave_data(server, room_id, &msg, result, response); |
271 let room = server.room(room_id); |
|
272 super::common::get_room_leave_data(server, room, &msg, result, response) |
|
273 } |
|
274 Err(_) => (), |
|
275 } |
|
276 } |
287 } |
277 |
288 |
278 server.remove_client(client_id); |
289 server.remove_client(client_id); |
279 |
290 |
280 response.add(LobbyLeft(nick, msg.clone()).send_all()); |
291 response.add(LobbyLeft(nick, msg.clone()).send_all()); |
332 let room = &server.rooms[room_id]; |
343 let room = &server.rooms[room_id]; |
333 if let Some(id) = room.master_id { |
344 if let Some(id) = room.master_id { |
334 response.add( |
345 response.add( |
335 ClientFlags( |
346 ClientFlags( |
336 add_flags(&[Flags::RoomMaster]), |
347 add_flags(&[Flags::RoomMaster]), |
337 vec![server.clients[id].nick.clone()], |
348 vec![server.client(id).nick.clone()], |
338 ) |
349 ) |
339 .send(to_client), |
350 .send(to_client), |
340 ); |
351 ); |
341 } |
352 } |
342 let nicks: Vec<_> = server |
353 let nicks = server.collect_nicks(|(_, c)| c.room_id == Some(room_id) && c.is_ready()); |
343 .clients |
354 |
344 .iter() |
|
345 .filter(|(_, c)| c.room_id == Some(room_id) && c.is_ready()) |
|
346 .map(|(_, c)| c.nick.clone()) |
|
347 .collect(); |
|
348 if !nicks.is_empty() { |
355 if !nicks.is_empty() { |
349 response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client)); |
356 response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client)); |
350 } |
357 } |
351 } |
358 } |
352 |
359 |
360 VoteType::Kick(nick) => { |
367 VoteType::Kick(nick) => { |
361 if let Some(client) = server.find_client(&nick) { |
368 if let Some(client) = server.find_client(&nick) { |
362 if client.room_id == Some(room_id) { |
369 if client.room_id == Some(room_id) { |
363 let id = client.id; |
370 let id = client.id; |
364 response.add(Kicked.send(id)); |
371 response.add(Kicked.send(id)); |
365 match server.leave_room(response.client_id) { |
372 let result = server.leave_room(id); |
366 Ok(result) => { |
373 get_room_leave_data(server, room_id, "kicked", result, response); |
367 let room = server.room(room_id); |
|
368 super::common::get_room_leave_data( |
|
369 server, room, "kicked", result, response, |
|
370 ) |
|
371 } |
|
372 Err(_) => (), |
|
373 } |
|
374 } |
374 } |
375 } |
375 } |
376 } |
376 } |
377 VoteType::Map(None) => (), |
377 VoteType::Map(None) => (), |
378 VoteType::Map(Some(name)) => { |
378 VoteType::Map(Some(name)) => { |
382 .send_all() |
382 .send_all() |
383 .in_room(room_id), |
383 .in_room(room_id), |
384 ); |
384 ); |
385 let room = &server.rooms[room_id]; |
385 let room = &server.rooms[room_id]; |
386 let room_master = if let Some(id) = room.master_id { |
386 let room_master = if let Some(id) = room.master_id { |
387 Some(&server.clients[id]) |
387 Some(server.client(id)) |
388 } else { |
388 } else { |
389 None |
389 None |
390 }; |
390 }; |
391 get_room_update(None, room, room_master, response); |
391 get_room_update(None, room, room_master, response); |
392 |
392 |
459 result |
459 result |
460 } |
460 } |
461 |
461 |
462 pub fn submit_vote(server: &mut HwServer, vote: Vote, response: &mut Response) { |
462 pub fn submit_vote(server: &mut HwServer, vote: Vote, response: &mut Response) { |
463 let client_id = response.client_id; |
463 let client_id = response.client_id; |
464 let client = &server.clients[client_id]; |
464 let client = server.client(client_id); |
465 |
465 |
466 if let Some(room_id) = client.room_id { |
466 if let Some(room_id) = client.room_id { |
467 let room = &mut server.rooms[room_id]; |
467 let room = server.room_mut(room_id); |
468 |
468 |
469 if let Some(res) = add_vote(room, response, vote) { |
469 if let Some(res) = add_vote(room, response, vote) { |
470 response.add( |
470 response.add( |
471 server_chat("Voting closed.".to_string()) |
471 server_chat("Voting closed.".to_string()) |
472 .send_all() |
472 .send_all() |
478 } |
478 } |
479 } |
479 } |
480 } |
480 } |
481 } |
481 } |
482 |
482 |
483 pub fn start_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) { |
483 pub fn get_start_game_data( |
484 let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server |
484 server: &HwServer, |
485 .clients |
485 room_id: RoomId, |
486 .iter() |
486 result: Result<Vec<String>, StartGameError>, |
487 .map(|(id, c)| (id, c.nick.clone())) |
487 response: &mut Response, |
488 .unzip(); |
488 ) { |
489 let room = &mut server.rooms[room_id]; |
489 match result { |
490 |
490 Ok(room_nicks) => { |
491 if !room.has_multiple_clans() { |
491 let room = server.room(room_id); |
492 response.add( |
492 response.add(RunGame.send_all().in_room(room.id)); |
493 Warning("The game can't be started with less than two clans!".to_string()).send_self(), |
493 response.add( |
494 ); |
494 ClientFlags(add_flags(&[Flags::InGame]), room_nicks) |
495 } else if room.protocol_number <= 43 && room.players_number != room.ready_players_number { |
495 .send_all() |
496 response.add(Warning("Not all players are ready".to_string()).send_self()); |
496 .in_room(room.id), |
497 } else if room.game_info.is_some() { |
497 ); |
498 response.add(Warning("The game is already in progress".to_string()).send_self()); |
498 |
499 } else { |
499 let room_master = room.master_id.map(|id| server.client(id)); |
500 room.start_round(); |
500 get_room_update(None, room, room_master, response); |
501 for id in room_clients { |
501 } |
502 let c = &mut server.clients[id]; |
502 Err(StartGameError::NotEnoughClans) => { |
503 c.set_is_in_game(true); |
503 response.warn("The game can't be started with less than two clans!") |
504 c.team_indices = room.client_team_indices(c.id); |
504 } |
505 } |
505 Err(StartGameError::NotEnoughTeams) => (), |
506 response.add(RunGame.send_all().in_room(room.id)); |
506 Err(StartGameError::NotReady) => response.warn("Not all players are ready"), |
507 response.add( |
507 Err(StartGameErrror) => response.warn("The game is already in progress"), |
508 ClientFlags(add_flags(&[Flags::InGame]), room_nicks) |
|
509 .send_all() |
|
510 .in_room(room.id), |
|
511 ); |
|
512 |
|
513 let room_master = if let Some(id) = room.master_id { |
|
514 Some(&server.clients[id]) |
|
515 } else { |
|
516 None |
|
517 }; |
|
518 get_room_update(None, room, room_master, response); |
|
519 } |
508 } |
520 } |
509 } |
521 |
510 |
522 pub fn end_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) { |
511 pub fn end_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) { |
523 let room = &mut server.rooms[room_id]; |
512 let room = &mut server.rooms[room_id]; |