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)) { |
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(); |