136 pub fn room_mut(&mut self, room_id: RoomId) -> &mut HwRoom { |
152 pub fn room_mut(&mut self, room_id: RoomId) -> &mut HwRoom { |
137 &mut self.rooms[room_id] |
153 &mut self.rooms[room_id] |
138 } |
154 } |
139 |
155 |
140 #[inline] |
156 #[inline] |
|
157 pub fn client_and_room(&self, client_id: ClientId, room_id: RoomId) -> (&HwClient, &HwRoom) { |
|
158 (&self.clients[client_id], &self.rooms[room_id]) |
|
159 } |
|
160 |
|
161 #[inline] |
|
162 pub fn client_and_room_mut( |
|
163 &mut self, |
|
164 client_id: ClientId, |
|
165 room_id: RoomId, |
|
166 ) -> (&mut HwClient, &mut HwRoom) { |
|
167 (&mut self.clients[client_id], &mut self.rooms[room_id]) |
|
168 } |
|
169 |
|
170 #[inline] |
141 pub fn is_admin(&self, client_id: ClientId) -> bool { |
171 pub fn is_admin(&self, client_id: ClientId) -> bool { |
142 self.clients |
172 self.clients |
143 .get(client_id) |
173 .get(client_id) |
144 .map(|c| c.is_admin()) |
174 .map(|c| c.is_admin()) |
145 .unwrap_or(false) |
175 .unwrap_or(false) |
242 } else { |
272 } else { |
243 Err(DoesntExist) |
273 Err(DoesntExist) |
244 } |
274 } |
245 } |
275 } |
246 |
276 |
|
277 pub fn leave_room(&mut self, client_id: ClientId) -> Result<LeaveRoomResult, LeaveRoomError> { |
|
278 let client = &mut self.clients[client_id]; |
|
279 if let Some(room_id) = client.room_id { |
|
280 let room = &mut self.rooms[room_id]; |
|
281 |
|
282 room.players_number -= 1; |
|
283 client.room_id = None; |
|
284 |
|
285 let is_empty = room.players_number == 0; |
|
286 let is_fixed = room.is_fixed(); |
|
287 let was_master = room.master_id == Some(client_id); |
|
288 let was_in_game = client.is_in_game(); |
|
289 let mut removed_teams = vec![]; |
|
290 |
|
291 if is_empty && !is_fixed { |
|
292 if client.is_ready() && room.ready_players_number > 0 { |
|
293 room.ready_players_number -= 1; |
|
294 } |
|
295 |
|
296 removed_teams = room |
|
297 .client_teams(client.id) |
|
298 .map(|t| t.name.clone()) |
|
299 .collect(); |
|
300 |
|
301 for team_name in &removed_teams { |
|
302 room.remove_team(team_name); |
|
303 } |
|
304 |
|
305 if client.is_master() && !is_fixed { |
|
306 client.set_is_master(false); |
|
307 room.master_id = None; |
|
308 } |
|
309 } |
|
310 |
|
311 client.set_is_ready(false); |
|
312 client.set_is_in_game(false); |
|
313 |
|
314 if !is_fixed { |
|
315 if room.players_number == 0 { |
|
316 self.rooms.remove(room_id); |
|
317 } else if room.master_id == None { |
|
318 let new_master_id = self.room_clients(room_id).next(); |
|
319 if let Some(new_master_id) = new_master_id { |
|
320 let room = &mut self.rooms[room_id]; |
|
321 room.master_id = Some(new_master_id); |
|
322 let new_master = &mut self.clients[new_master_id]; |
|
323 new_master.set_is_master(true); |
|
324 |
|
325 if room.protocol_number < 42 { |
|
326 room.name = new_master.nick.clone(); |
|
327 } |
|
328 |
|
329 room.set_join_restriction(false); |
|
330 room.set_team_add_restriction(false); |
|
331 room.set_unregistered_players_restriction(true); |
|
332 } |
|
333 } |
|
334 } |
|
335 |
|
336 if is_empty && !is_fixed { |
|
337 Ok(LeaveRoomResult::RoomRemoved) |
|
338 } else { |
|
339 Ok(LeaveRoomResult::RoomRemains { |
|
340 is_empty, |
|
341 was_master, |
|
342 was_in_game, |
|
343 new_master: self.rooms[room_id].master_id, |
|
344 removed_teams, |
|
345 }) |
|
346 } |
|
347 } else { |
|
348 Err(LeaveRoomError::NoRoom) |
|
349 } |
|
350 } |
|
351 |
247 #[inline] |
352 #[inline] |
248 pub fn set_var(&mut self, client_id: ClientId, var: ServerVar) -> Result<(), AccessError> { |
353 pub fn set_var(&mut self, client_id: ClientId, var: ServerVar) -> Result<(), AccessError> { |
249 if self.clients[client_id].is_admin() { |
354 if self.clients[client_id].is_admin() { |
250 match var { |
355 match var { |
251 ServerVar::MOTDNew(msg) => self.greetings.for_latest_protocol = msg, |
356 ServerVar::MOTDNew(msg) => self.greetings.for_latest_protocol = msg, |