# HG changeset patch # User alfadur # Date 1711371911 -10800 # Node ID d9f1b239b6d7a4d69c3bd578e5ccad5e38aa6e77 # Parent d73e6cb37f83a8e23c69b1b9858411e46fd93a64 fix rejoining diff -r d73e6cb37f83 -r d9f1b239b6d7 rust/hedgewars-server/src/core/room.rs --- a/rust/hedgewars-server/src/core/room.rs Mon Mar 25 15:59:14 2024 +0300 +++ b/rust/hedgewars-server/src/core/room.rs Mon Mar 25 16:05:11 2024 +0300 @@ -14,18 +14,25 @@ pub const MAX_TEAMS_IN_ROOM: u8 = 8; pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM; +#[derive(Clone, Debug)] +pub struct OwnedTeam { + pub owner_id: ClientId, + pub owner_nick: String, + pub info: TeamInfo, +} + fn client_teams_impl( - teams: &[(ClientId, TeamInfo)], - client_id: ClientId, + teams: &[OwnedTeam], + owner_id: ClientId, ) -> impl Iterator + Clone { teams .iter() - .filter(move |(id, _)| *id == client_id) - .map(|(_, t)| t) + .filter(move |team| team.owner_id == owner_id) + .map(|team| &team.info) } pub struct GameInfo { - pub original_teams: Vec<(ClientId, TeamInfo)>, + pub original_teams: Vec, pub left_teams: Vec, pub msg_log: Vec, pub sync_msg: Option, @@ -34,7 +41,7 @@ } impl GameInfo { - fn new(teams: Vec<(ClientId, TeamInfo)>, config: RoomConfig) -> GameInfo { + fn new(teams: Vec, config: RoomConfig) -> GameInfo { GameInfo { left_teams: Vec::new(), msg_log: Vec::new(), @@ -45,8 +52,18 @@ } } - pub fn client_teams(&self, client_id: ClientId) -> impl Iterator + Clone { - client_teams_impl(&self.original_teams, client_id) + pub fn client_teams(&self, owner_id: ClientId) -> impl Iterator + Clone { + client_teams_impl(&self.original_teams, owner_id) + } + + pub fn client_teams_by_nick<'a>( + &'a self, + owner_nick: &'a str, + ) -> impl Iterator + Clone + 'a { + self.original_teams + .iter() + .filter(move |team| team.owner_nick == owner_nick) + .map(|team| &team.info) } pub fn mark_left_teams<'a, I>(&mut self, team_names: I) @@ -95,7 +112,7 @@ pub default_hedgehog_number: u8, pub max_teams: u8, pub ready_players_number: u8, - pub teams: Vec<(ClientId, TeamInfo)>, + pub teams: Vec, config: RoomConfig, pub voting: Option, pub saves: HashMap, @@ -125,7 +142,10 @@ } pub fn hedgehogs_number(&self) -> u8 { - self.teams.iter().map(|(_, t)| t.hedgehogs_number).sum() + self.teams + .iter() + .map(|team| team.info.hedgehogs_number) + .sum() } pub fn addable_hedgehogs(&self) -> u8 { @@ -134,7 +154,7 @@ pub fn add_team( &mut self, - owner_id: ClientId, + owner: &HwClient, mut team: TeamInfo, preserve_color: bool, ) -> &TeamInfo { @@ -142,24 +162,32 @@ team.color = iter::repeat(()) .enumerate() .map(|(i, _)| i as u8) - .take(u8::max_value() as usize + 1) - .find(|i| self.teams.iter().all(|(_, t)| t.color != *i)) + .take(u8::MAX as usize + 1) + .find(|i| self.teams.iter().all(|team| team.info.color != *i)) .unwrap_or(0u8) }; team.hedgehogs_number = if self.teams.is_empty() { self.default_hedgehog_number } else { self.teams[0] - .1 + .info .hedgehogs_number .min(self.addable_hedgehogs()) }; - self.teams.push((owner_id, team)); - &self.teams.last().unwrap().1 + self.teams.push(OwnedTeam { + owner_id: owner.id, + owner_nick: owner.nick.clone(), + info: team, + }); + &self.teams.last().unwrap().info } pub fn remove_team(&mut self, team_name: &str) { - if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) { + if let Some(index) = self + .teams + .iter() + .position(|team| team.info.name == team_name) + { self.teams.remove(index); } } @@ -169,9 +197,9 @@ let teams = &mut self.teams; if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM { - for (_, team) in teams.iter_mut() { - team.hedgehogs_number = n; - names.push(team.name.clone()) + for team in teams.iter_mut() { + team.info.hedgehogs_number = n; + names.push(team.info.name.clone()) } self.default_hedgehog_number = n; } @@ -190,8 +218,8 @@ { self.teams .iter_mut() - .find(|(_, t)| f(t)) - .map(|(id, t)| (*id, t)) + .find(|team| f(&team.info)) + .map(|team| (team.owner_id, &mut team.info)) } pub fn find_team(&self, f: F) -> Option<&TeamInfo> @@ -200,18 +228,18 @@ { self.teams .iter() - .find_map(|(_, t)| Some(t).filter(|t| f(&t))) + .find_map(|team| Some(&team.info).filter(|t| f(&t))) } - pub fn client_teams(&self, client_id: ClientId) -> impl Iterator { - client_teams_impl(&self.teams, client_id) + pub fn client_teams(&self, owner_id: ClientId) -> impl Iterator { + client_teams_impl(&self.teams, owner_id) } pub fn client_team_indices(&self, client_id: ClientId) -> Vec { self.teams .iter() .enumerate() - .filter(move |(_, (id, _))| *id == client_id) + .filter(move |(_, team)| team.owner_id == client_id) .map(|(i, _)| i as u8) .collect() } @@ -219,15 +247,15 @@ pub fn clan_team_owners(&self, color: u8) -> impl Iterator + '_ { self.teams .iter() - .filter(move |(_, t)| t.color == color) - .map(|(id, _)| *id) + .filter(move |team| team.info.color == color) + .map(|team| team.owner_id) } pub fn find_team_owner(&self, team_name: &str) -> Option<(ClientId, &str)> { self.teams .iter() - .find(|(_, t)| t.name == team_name) - .map(|(id, t)| (*id, &t.name[..])) + .find(|team| team.info.name == team_name) + .map(|team| (team.owner_id, &team.info.name[..])) } pub fn find_team_color(&self, owner_id: ClientId) -> Option { @@ -235,8 +263,8 @@ } pub fn has_multiple_clans(&self) -> bool { - self.teams.iter().min_by_key(|(_, t)| t.color) - != self.teams.iter().max_by_key(|(_, t)| t.color) + let colors = self.teams.iter().map(|team| team.info.color); + colors.clone().min() != colors.max() } pub fn set_config(&mut self, cfg: GameCfg) { diff -r d73e6cb37f83 -r d9f1b239b6d7 rust/hedgewars-server/src/core/server.rs --- a/rust/hedgewars-server/src/core/server.rs Mon Mar 25 15:59:14 2024 +0300 +++ b/rust/hedgewars-server/src/core/server.rs Mon Mar 25 16:05:11 2024 +0300 @@ -361,7 +361,7 @@ Err(Restricted) } else if room.is_registration_required() { Err(RegistrationRequired) - } else if room.players_number == u8::max_value() { + } else if room.players_number == u8::MAX { Err(Full) } else { move_to_room(client, room); @@ -620,7 +620,10 @@ } fn remove_from_room(&mut self, client_id: ClientId) -> LeaveRoomResult { - let (client, room) = self.server.client_and_room_mut(client_id).expect("Caller should have ensured the client is in this room"); + let (client, room) = self + .server + .client_and_room_mut(client_id) + .expect("Caller should have ensured the client is in this room"); room.players_number -= 1; client.room_id = None; @@ -937,7 +940,7 @@ Err(Restricted) } else { info.owner = client.nick.clone(); - let team = room.add_team(client.id, *info, client.protocol_number < 42); + let team = room.add_team(&client, *info, client.protocol_number < 42); client.teams_in_game += 1; client.clan = Some(team.color); Ok(team) @@ -949,7 +952,7 @@ let (client, room) = self.get_mut(); match room.find_team_owner(team_name) { None => Err(NoTeam), - Some((id, _)) if id != client.id => Err(RemoveTeamError::TeamNotOwned), + Some((id, _)) if id != client.id => Err(TeamNotOwned), Some(_) => { client.teams_in_game -= 1; client.clan = room.find_team_color(client.id); @@ -1171,14 +1174,22 @@ client.room_id = Some(room.id); client.set_is_in_game(room.game_info.is_some()); - if let Some(ref mut info) = room.game_info { - let teams = info.client_teams(client.id); - client.teams_in_game = teams.clone().count() as u8; - client.clan = teams.clone().next().map(|t| t.color); - let team_names: Vec<_> = teams.map(|t| t.name.clone()).collect(); + #[cfg(feature = "official-server")] + let can_rejoin = client.is_registered(); + + #[cfg(not(feature = "official-server"))] + let can_rejoin = true; - if !team_names.is_empty() { - info.left_teams.retain(|name| !team_names.contains(&name)); + if can_rejoin { + if let Some(ref mut info) = room.game_info { + let teams = info.client_teams_by_nick(&client.nick); + client.teams_in_game = teams.clone().count() as u8; + client.clan = teams.clone().next().map(|t| t.color); + let team_names: Vec<_> = teams.map(|t| t.name.clone()).collect(); + + if !team_names.is_empty() { + info.left_teams.retain(|name| !team_names.contains(&name)); + } } } } diff -r d73e6cb37f83 -r d9f1b239b6d7 rust/hedgewars-server/src/handlers/common.rs --- a/rust/hedgewars-server/src/handlers/common.rs Mon Mar 25 15:59:14 2024 +0300 +++ b/rust/hedgewars-server/src/handlers/common.rs Mon Mar 25 16:05:11 2024 +0300 @@ -211,20 +211,24 @@ response.add(ForwardEngineMessage(vec![to_engine_msg(once(b'I'))]).send_self()); } - for (_, original_team) in &info.original_teams { - if let Some(team) = room.find_team(|team| team.name == original_team.name) { - if team != original_team { - response.add(TeamRemove(original_team.name.clone()).send_self()); + for original_team in &info.original_teams { + if let Some(team) = room.find_team(|team| team.name == original_team.info.name) { + if *team != original_team.info { + response.add(TeamRemove(original_team.info.name.clone()).send_self()); response.add(TeamAdd(team.to_protocol()).send_self()); } } else { - response.add(TeamRemove(original_team.name.clone()).send_self()); + response.add(TeamRemove(original_team.info.name.clone()).send_self()); } } - for (_, team) in &room.teams { - if !info.original_teams.iter().any(|(_, t)| t.name == team.name) { - response.add(TeamAdd(team.to_protocol()).send_self()); + for team in &room.teams { + if !info + .original_teams + .iter() + .any(|original_team| original_team.info.name == team.info.name) + { + response.add(TeamAdd(team.info.to_protocol()).send_self()); } } @@ -403,7 +407,11 @@ None => &room.teams, }; - get_teams(current_teams.iter().map(|(_, t)| t), destination, response); + get_teams( + current_teams.iter().map(|team| &team.info), + destination, + response, + ); } pub fn get_room_flags( diff -r d73e6cb37f83 -r d9f1b239b6d7 rust/hedgewars-server/src/handlers/inroom.rs --- a/rust/hedgewars-server/src/handlers/inroom.rs Mon Mar 25 15:59:14 2024 +0300 +++ b/rust/hedgewars-server/src/handlers/inroom.rs Mon Mar 25 16:05:11 2024 +0300 @@ -496,6 +496,6 @@ response.warn("The player is not in your room.") } }, - _ => warn!("Unimplemented!"), + message => warn!("Unimplemented: {:?}", message), } } diff -r d73e6cb37f83 -r d9f1b239b6d7 rust/hedgewars-server/src/protocol.rs --- a/rust/hedgewars-server/src/protocol.rs Mon Mar 25 15:59:14 2024 +0300 +++ b/rust/hedgewars-server/src/protocol.rs Mon Mar 25 16:05:11 2024 +0300 @@ -87,7 +87,10 @@ Err(nom::Err::Incomplete(_)) => {} Err(nom::Err::Failure(e) | nom::Err::Error(e)) => { debug!("Invalid message: {:?}", e); - trace!("Buffer content: {:?}", String::from_utf8_lossy(&self.buffer[..])); + trace!( + "Buffer content: {:?}", + String::from_utf8_lossy(&self.buffer[..]) + ); self.recover(); } } diff -r d73e6cb37f83 -r d9f1b239b6d7 rust/hedgewars-server/src/server/network.rs --- a/rust/hedgewars-server/src/server/network.rs Mon Mar 25 15:59:14 2024 +0300 +++ b/rust/hedgewars-server/src/server/network.rs Mon Mar 25 16:05:11 2024 +0300 @@ -216,7 +216,7 @@ server_state: ServerState, clients: Slab>, update_tx: Sender, - update_rx: Receiver + update_rx: Receiver, } impl NetworkLayer { @@ -448,7 +448,7 @@ server_state, clients, update_tx, - update_rx + update_rx, } } }