1 use crate::{ |
1 use crate::{ |
|
2 core::{ |
|
3 client::HwClient, |
|
4 room::HwRoom, |
|
5 server::HwServer, |
|
6 types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType}, |
|
7 }, |
2 protocol::messages::{ |
8 protocol::messages::{ |
3 server_chat, |
9 add_flags, remove_flags, server_chat, |
4 add_flags, remove_flags, |
10 HwProtocolMessage::{self, Rnd}, |
5 HWProtocolMessage::{self, Rnd}, |
11 HwServerMessage::{self, *}, |
6 HWServerMessage::{self, *}, |
|
7 ProtocolFlags as Flags, |
12 ProtocolFlags as Flags, |
8 }, |
|
9 core::{ |
|
10 client::HWClient, |
|
11 server::HWServer, |
|
12 types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType}, |
|
13 room::HWRoom, |
|
14 }, |
13 }, |
15 utils::to_engine_msg, |
14 utils::to_engine_msg, |
16 }; |
15 }; |
17 |
16 |
18 use super::Response; |
17 use super::Response; |
19 |
18 |
20 use crate::core::types::RoomConfig; |
19 use crate::core::types::RoomConfig; |
21 use rand::{self, seq::SliceRandom, thread_rng, Rng}; |
20 use rand::{self, seq::SliceRandom, thread_rng, Rng}; |
22 use std::{iter::once, mem::replace}; |
21 use std::{iter::once, mem::replace}; |
23 |
22 |
24 pub fn rnd_reply(options: &[String]) -> HWServerMessage { |
23 pub fn rnd_reply(options: &[String]) -> HwServerMessage { |
25 let mut rng = thread_rng(); |
24 let mut rng = thread_rng(); |
26 |
25 |
27 let reply = if options.is_empty() { |
26 let reply = if options.is_empty() { |
28 (*&["heads", "tails"].choose(&mut rng).unwrap()).to_string() |
27 (*&["heads", "tails"].choose(&mut rng).unwrap()).to_string() |
29 } else { |
28 } else { |
34 nick: "[random]".to_string(), |
33 nick: "[random]".to_string(), |
35 msg: reply, |
34 msg: reply, |
36 } |
35 } |
37 } |
36 } |
38 |
37 |
39 pub fn join_lobby(server: &mut HWServer, response: &mut Response) { |
38 pub fn join_lobby(server: &mut HwServer, response: &mut Response) { |
40 let client_id = response.client_id(); |
39 let client_id = response.client_id(); |
41 |
40 |
42 let client = &server.clients[client_id]; |
41 let client = &server.clients[client_id]; |
43 let nick = vec![client.nick.clone()]; |
42 let nick = vec![client.nick.clone()]; |
44 let mut flags = vec![]; |
43 let mut flags = vec![]; |
98 response.add(server_msg.send_self()); |
97 response.add(server_msg.send_self()); |
99 response.add(rooms_msg.send_self()); |
98 response.add(rooms_msg.send_self()); |
100 } |
99 } |
101 |
100 |
102 pub fn remove_teams( |
101 pub fn remove_teams( |
103 room: &mut HWRoom, |
102 room: &mut HwRoom, |
104 team_names: Vec<String>, |
103 team_names: Vec<String>, |
105 is_in_game: bool, |
104 is_in_game: bool, |
106 response: &mut Response, |
105 response: &mut Response, |
107 ) { |
106 ) { |
108 if let Some(ref mut info) = room.game_info { |
107 if let Some(ref mut info) = room.game_info { |
142 response.add(TeamRemove(team_name).send_all().in_room(room.id)); |
141 response.add(TeamRemove(team_name).send_all().in_room(room.id)); |
143 } |
142 } |
144 } |
143 } |
145 |
144 |
146 fn remove_client_from_room( |
145 fn remove_client_from_room( |
147 client: &mut HWClient, |
146 client: &mut HwClient, |
148 room: &mut HWRoom, |
147 room: &mut HwRoom, |
149 response: &mut Response, |
148 response: &mut Response, |
150 msg: &str, |
149 msg: &str, |
151 ) { |
150 ) { |
152 room.players_number -= 1; |
151 room.players_number -= 1; |
153 if room.players_number > 0 || room.is_fixed() { |
152 if room.players_number > 0 || room.is_fixed() { |
195 |
194 |
196 response.add(ClientFlags(remove_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_all()); |
195 response.add(ClientFlags(remove_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_all()); |
197 } |
196 } |
198 |
197 |
199 pub fn change_master( |
198 pub fn change_master( |
200 server: &mut HWServer, |
199 server: &mut HwServer, |
201 room_id: RoomId, |
200 room_id: RoomId, |
202 new_master_id: ClientId, |
201 new_master_id: ClientId, |
203 response: &mut Response, |
202 response: &mut Response, |
204 ) { |
203 ) { |
205 let room = &mut server.rooms[room_id]; |
204 let room = &mut server.rooms[room_id]; |
269 .send_self(), |
268 .send_self(), |
270 ); |
269 ); |
271 } |
270 } |
272 } |
271 } |
273 |
272 |
274 pub fn exit_room(server: &mut HWServer, client_id: ClientId, response: &mut Response, msg: &str) { |
273 pub fn exit_room(server: &mut HwServer, client_id: ClientId, response: &mut Response, msg: &str) { |
275 let client = &mut server.clients[client_id]; |
274 let client = &mut server.clients[client_id]; |
276 |
275 |
277 if let Some(room_id) = client.room_id { |
276 if let Some(room_id) = client.room_id { |
278 let room = &mut server.rooms[room_id]; |
277 let room = &mut server.rooms[room_id]; |
279 |
278 |
307 } |
306 } |
308 } |
307 } |
309 } |
308 } |
310 } |
309 } |
311 |
310 |
312 pub fn remove_client(server: &mut HWServer, response: &mut Response, msg: String) { |
311 pub fn remove_client(server: &mut HwServer, response: &mut Response, msg: String) { |
313 let client_id = response.client_id(); |
312 let client_id = response.client_id(); |
314 let client = &mut server.clients[client_id]; |
313 let client = &mut server.clients[client_id]; |
315 let nick = client.nick.clone(); |
314 let nick = client.nick.clone(); |
316 |
315 |
317 exit_room(server, client_id, response, &msg); |
316 exit_room(server, client_id, response, &msg); |
323 response.remove_client(client_id); |
322 response.remove_client(client_id); |
324 } |
323 } |
325 |
324 |
326 pub fn get_room_update( |
325 pub fn get_room_update( |
327 room_name: Option<String>, |
326 room_name: Option<String>, |
328 room: &HWRoom, |
327 room: &HwRoom, |
329 master: Option<&HWClient>, |
328 master: Option<&HwClient>, |
330 response: &mut Response, |
329 response: &mut Response, |
331 ) { |
330 ) { |
332 let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master)); |
331 let update_msg = RoomUpdated(room_name.unwrap_or(room.name.clone()), room.info(master)); |
333 response.add(update_msg.send_all().with_protocol(room.protocol_number)); |
332 response.add(update_msg.send_all().with_protocol(room.protocol_number)); |
334 } |
333 } |
338 for cfg in config.to_game_config() { |
337 for cfg in config.to_game_config() { |
339 response.add(cfg.to_server_msg().send(to_client)); |
338 response.add(cfg.to_server_msg().send(to_client)); |
340 } |
339 } |
341 } |
340 } |
342 |
341 |
343 pub fn get_room_config(room: &HWRoom, to_client: ClientId, response: &mut Response) { |
342 pub fn get_room_config(room: &HwRoom, to_client: ClientId, response: &mut Response) { |
344 get_room_config_impl(room.active_config(), to_client, response); |
343 get_room_config_impl(room.active_config(), to_client, response); |
345 } |
344 } |
346 |
345 |
347 pub fn get_teams<'a, I>(teams: I, to_client: ClientId, response: &mut Response) |
346 pub fn get_teams<'a, I>(teams: I, to_client: ClientId, response: &mut Response) |
348 where |
347 where |
354 response.add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send(to_client)); |
353 response.add(HedgehogsNumber(team.name.clone(), team.hedgehogs_number).send(to_client)); |
355 } |
354 } |
356 } |
355 } |
357 |
356 |
358 pub fn get_room_teams( |
357 pub fn get_room_teams( |
359 server: &HWServer, |
358 server: &HwServer, |
360 room_id: RoomId, |
359 room_id: RoomId, |
361 to_client: ClientId, |
360 to_client: ClientId, |
362 response: &mut Response, |
361 response: &mut Response, |
363 ) { |
362 ) { |
364 let room = &server.rooms[room_id]; |
363 let room = &server.rooms[room_id]; |
369 |
368 |
370 get_teams(current_teams.iter().map(|(_, t)| t), to_client, response); |
369 get_teams(current_teams.iter().map(|(_, t)| t), to_client, response); |
371 } |
370 } |
372 |
371 |
373 pub fn get_room_flags( |
372 pub fn get_room_flags( |
374 server: &HWServer, |
373 server: &HwServer, |
375 room_id: RoomId, |
374 room_id: RoomId, |
376 to_client: ClientId, |
375 to_client: ClientId, |
377 response: &mut Response, |
376 response: &mut Response, |
378 ) { |
377 ) { |
379 let room = &server.rooms[room_id]; |
378 let room = &server.rooms[room_id]; |
396 response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client)); |
395 response.add(ClientFlags(add_flags(&[Flags::Ready]), nicks).send(to_client)); |
397 } |
396 } |
398 } |
397 } |
399 |
398 |
400 pub fn apply_voting_result( |
399 pub fn apply_voting_result( |
401 server: &mut HWServer, |
400 server: &mut HwServer, |
402 room_id: RoomId, |
401 room_id: RoomId, |
403 response: &mut Response, |
402 response: &mut Response, |
404 kind: VoteType, |
403 kind: VoteType, |
405 ) { |
404 ) { |
406 match kind { |
405 match kind { |
468 ); |
467 ); |
469 } |
468 } |
470 } |
469 } |
471 } |
470 } |
472 |
471 |
473 fn add_vote(room: &mut HWRoom, response: &mut Response, vote: Vote) -> Option<bool> { |
472 fn add_vote(room: &mut HwRoom, response: &mut Response, vote: Vote) -> Option<bool> { |
474 let client_id = response.client_id; |
473 let client_id = response.client_id; |
475 let mut result = None; |
474 let mut result = None; |
476 |
475 |
477 if let Some(ref mut voting) = room.voting { |
476 if let Some(ref mut voting) = room.voting { |
478 if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) { |
477 if vote.is_forced || voting.votes.iter().all(|(id, _)| client_id != *id) { |
496 } |
495 } |
497 |
496 |
498 result |
497 result |
499 } |
498 } |
500 |
499 |
501 pub fn submit_vote(server: &mut HWServer, vote: Vote, response: &mut Response) { |
500 pub fn submit_vote(server: &mut HwServer, vote: Vote, response: &mut Response) { |
502 let client_id = response.client_id; |
501 let client_id = response.client_id; |
503 let client = &server.clients[client_id]; |
502 let client = &server.clients[client_id]; |
504 |
503 |
505 if let Some(room_id) = client.room_id { |
504 if let Some(room_id) = client.room_id { |
506 let room = &mut server.rooms[room_id]; |
505 let room = &mut server.rooms[room_id]; |
517 } |
516 } |
518 } |
517 } |
519 } |
518 } |
520 } |
519 } |
521 |
520 |
522 pub fn start_game(server: &mut HWServer, room_id: RoomId, response: &mut Response) { |
521 pub fn start_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) { |
523 let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server |
522 let (room_clients, room_nicks): (Vec<_>, Vec<_>) = server |
524 .clients |
523 .clients |
525 .iter() |
524 .iter() |
526 .map(|(id, c)| (id, c.nick.clone())) |
525 .map(|(id, c)| (id, c.nick.clone())) |
527 .unzip(); |
526 .unzip(); |
556 }; |
555 }; |
557 get_room_update(None, room, room_master, response); |
556 get_room_update(None, room, room_master, response); |
558 } |
557 } |
559 } |
558 } |
560 |
559 |
561 pub fn end_game(server: &mut HWServer, room_id: RoomId, response: &mut Response) { |
560 pub fn end_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) { |
562 let room = &mut server.rooms[room_id]; |
561 let room = &mut server.rooms[room_id]; |
563 room.ready_players_number = 1; |
562 room.ready_players_number = 1; |
564 let room_master = if let Some(id) = room.master_id { |
563 let room_master = if let Some(id) = room.master_id { |
565 Some(&server.clients[id]) |
564 Some(&server.clients[id]) |
566 } else { |
565 } else { |
611 } |
610 } |
612 |
611 |
613 #[cfg(test)] |
612 #[cfg(test)] |
614 mod tests { |
613 mod tests { |
615 use super::*; |
614 use super::*; |
616 use crate::protocol::messages::HWServerMessage::ChatMsg; |
615 use crate::protocol::messages::HwServerMessage::ChatMsg; |
617 use crate::server::actions::PendingMessage; |
616 use crate::server::actions::PendingMessage; |
618 |
617 |
619 fn reply2string(r: HWServerMessage) -> String { |
618 fn reply2string(r: HwServerMessage) -> String { |
620 match r { |
619 match r { |
621 ChatMsg { msg: p, .. } => String::from(p), |
620 ChatMsg { msg: p, .. } => String::from(p), |
622 _ => panic!("expected a ChatMsg"), |
621 _ => panic!("expected a ChatMsg"), |
623 } |
622 } |
624 } |
623 } |