--- a/rust/hedgewars-server/src/core/server.rs Sat Nov 30 02:54:49 2019 +0100
+++ b/rust/hedgewars-server/src/core/server.rs Tue Dec 17 18:54:17 2019 +0300
@@ -6,11 +6,10 @@
};
use crate::{protocol::messages::HwProtocolMessage::Greeting, utils};
-use crate::core::server::JoinRoomError::WrongProtocol;
use bitflags::*;
use log::*;
use slab;
-use std::{borrow::BorrowMut, collections::HashSet, iter, num::NonZeroU16};
+use std::{borrow::BorrowMut, collections::HashSet, iter, mem::replace, num::NonZeroU16};
type Slab<T> = slab::Slab<T>;
@@ -67,6 +66,13 @@
}
#[derive(Debug)]
+pub struct EndGameResult {
+ pub joined_mid_game_clients: Vec<ClientId>,
+ pub left_teams: Vec<String>,
+ pub unreadied_nicks: Vec<String>,
+}
+
+#[derive(Debug)]
pub struct UninitializedError();
#[derive(Debug)]
pub struct AccessError();
@@ -441,6 +447,46 @@
}
}
+ pub fn end_game(&mut self, room_id: RoomId) -> EndGameResult {
+ let room = &mut self.rooms[room_id];
+ room.ready_players_number = 1;
+
+ if let Some(info) = replace(&mut room.game_info, None) {
+ let joined_mid_game_clients = self
+ .clients
+ .iter()
+ .filter(|(_, c)| c.room_id == Some(room_id) && c.is_joined_mid_game())
+ .map(|(_, c)| c.id)
+ .collect();
+
+ let unreadied_nicks: Vec<_> = self
+ .clients
+ .iter_mut()
+ .filter(|(_, c)| c.room_id == Some(room_id))
+ .map(|(_, c)| {
+ c.set_is_ready(c.is_master());
+ c.set_is_joined_mid_game(false);
+ c
+ })
+ .filter_map(|c| {
+ if !c.is_master() {
+ Some(c.nick.clone())
+ } else {
+ None
+ }
+ })
+ .collect();
+
+ EndGameResult {
+ joined_mid_game_clients,
+ left_teams: info.left_teams.clone(),
+ unreadied_nicks,
+ }
+ } else {
+ unreachable!()
+ }
+ }
+
#[inline]
pub fn set_var(&mut self, client_id: ClientId, var: ServerVar) -> Result<(), AccessError> {
if self.clients[client_id].is_admin() {
--- a/rust/hedgewars-server/src/handlers/common.rs Sat Nov 30 02:54:49 2019 +0100
+++ b/rust/hedgewars-server/src/handlers/common.rs Tue Dec 17 18:54:17 2019 +0300
@@ -2,7 +2,9 @@
core::{
client::HwClient,
room::HwRoom,
- server::{HwServer, JoinRoomError, LeaveRoomError, LeaveRoomResult, StartGameError},
+ server::{
+ EndGameResult, HwServer, JoinRoomError, LeaveRoomError, LeaveRoomResult, StartGameError,
+ },
types::{ClientId, GameCfg, RoomId, TeamInfo, Vote, VoteType},
},
protocol::messages::{
@@ -204,7 +206,7 @@
let client = server.client(response.client_id);
response.add(ClientFlags(remove_flags(&[Flags::InRoom]), vec![client.nick.clone()]).send_all());
- match (result) {
+ match result {
LeaveRoomResult::RoomRemoved => {
response.add(
RoomRemove(room.name.clone())
@@ -504,57 +506,41 @@
}
Err(StartGameError::NotEnoughTeams) => (),
Err(StartGameError::NotReady) => response.warn("Not all players are ready"),
- Err(StartGameErrror) => response.warn("The game is already in progress"),
+ Err(StartGameError::AlreadyInGame) => response.warn("The game is already in progress"),
}
}
-pub fn end_game(server: &mut HwServer, room_id: RoomId, response: &mut Response) {
- let room = &mut server.rooms[room_id];
- room.ready_players_number = 1;
+pub fn get_end_game_result(
+ server: &HwServer,
+ room_id: RoomId,
+ result: EndGameResult,
+ response: &mut Response,
+) {
+ let room = server.room(room_id);
let room_master = if let Some(id) = room.master_id {
- Some(&server.clients[id])
+ Some(server.client(id))
} else {
None
};
+
get_room_update(None, room, room_master, response);
response.add(RoundFinished.send_all().in_room(room_id));
- if let Some(info) = replace(&mut room.game_info, None) {
- for (_, client) in server.clients.iter() {
- if client.room_id == Some(room_id) && client.is_joined_mid_game() {
- super::common::get_room_config(room, client.id, response);
- response.extend(
- info.left_teams
- .iter()
- .map(|name| TeamRemove(name.clone()).send(client.id)),
- );
- }
- }
+ for client_id in result.joined_mid_game_clients {
+ super::common::get_room_config(room, client_id, response);
+ response.extend(
+ result
+ .left_teams
+ .iter()
+ .map(|name| TeamRemove(name.clone()).send(client_id)),
+ );
}
- let nicks: Vec<_> = server
- .clients
- .iter_mut()
- .filter(|(_, c)| c.room_id == Some(room_id))
- .map(|(_, c)| {
- c.set_is_ready(c.is_master());
- c.set_is_joined_mid_game(false);
- c
- })
- .filter_map(|c| {
- if !c.is_master() {
- Some(c.nick.clone())
- } else {
- None
- }
- })
- .collect();
-
- if !nicks.is_empty() {
+ if !result.unreadied_nicks.is_empty() {
let msg = if room.protocol_number < 38 {
- LegacyReady(false, nicks)
+ LegacyReady(false, result.unreadied_nicks)
} else {
- ClientFlags(remove_flags(&[Flags::Ready]), nicks)
+ ClientFlags(remove_flags(&[Flags::Ready]), result.unreadied_nicks)
};
response.add(msg.send_all().in_room(room_id));
}
--- a/rust/hedgewars-server/src/handlers/inroom.rs Sat Nov 30 02:54:49 2019 +0100
+++ b/rust/hedgewars-server/src/handlers/inroom.rs Tue Dec 17 18:54:17 2019 +0300
@@ -274,7 +274,8 @@
match room.game_info {
Some(ref info) if info.teams_in_game == 0 => {
- super::common::end_game(server, room_id, response)
+ let result = server.end_game(room_id);
+ super::common::get_end_game_result(server, room_id, result, response);
}
_ => (),
}
@@ -566,7 +567,8 @@
}
}
if game_ended {
- super::common::end_game(server, room_id, response)
+ let result = server.end_game(room_id);
+ super::common::get_end_game_result(server, room_id, result, response);
}
}
Rnd(v) => {