# HG changeset patch # User alfadur # Date 1576877177 -10800 # Node ID e705d30e0f1082960bd41b31655af8476630881b # Parent abd5eb80716662e7b71ac9deab6189837443c914 some more room handler cleanup diff -r abd5eb807166 -r e705d30e0f10 rust/hedgewars-server/src/core/server.rs --- a/rust/hedgewars-server/src/core/server.rs Thu Dec 19 23:13:58 2019 +0300 +++ b/rust/hedgewars-server/src/core/server.rs Sat Dec 21 00:26:17 2019 +0300 @@ -26,6 +26,7 @@ Restricted, } +#[derive(Debug)] pub enum LeaveRoomResult { RoomRemoved, RoomRemains { @@ -57,6 +58,19 @@ } #[derive(Debug)] +pub enum ModifyTeamError { + NoTeam, + NotMaster, +} + +#[derive(Debug)] +pub enum ModifyRoomNameError { + AccessDenied, + InvalidName, + DuplicateName, +} + +#[derive(Debug)] pub enum StartGameError { NotEnoughClans, NotEnoughTeams, @@ -210,7 +224,7 @@ } #[inline] - pub fn client_mut(&mut self, client_id: ClientId) -> &mut HwClient { + fn client_mut(&mut self, client_id: ClientId) -> &mut HwClient { &mut self.clients[client_id] } @@ -530,6 +544,73 @@ } } + pub fn enable_super_power(&mut self, client_id: ClientId) -> bool { + let client = &mut self.clients[client_id]; + if client.is_admin() { + client.set_has_super_power(true); + } + client.is_admin() + } + + pub fn set_room_name( + &mut self, + client_id: ClientId, + room_id: RoomId, + mut name: String, + ) -> Result { + let room_exists = self.has_room(&name); + let room = &mut self.rooms[room_id]; + if room.is_fixed() || room.master_id != Some(client_id) { + Err(ModifyRoomNameError::AccessDenied) + } else if utils::is_name_illegal(&name) { + Err(ModifyRoomNameError::InvalidName) + } else if room_exists { + Err(ModifyRoomNameError::DuplicateName) + } else { + std::mem::swap(&mut room.name, &mut name); + Ok(name) + } + } + + pub fn add_team(&mut self, client_id: ClientId) {} + + pub fn set_team_color( + &mut self, + client_id: ClientId, + room_id: RoomId, + team_name: &str, + color: u8, + ) -> Result<(), ModifyTeamError> { + let client = &self.clients[client_id]; + let room = &mut self.rooms[room_id]; + if let Some((owner, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) { + if !client.is_master() { + Err(ModifyTeamError::NotMaster) + } else { + team.color = color; + self.clients[owner].clan = Some(color); + Ok(()) + } + } else { + Err(ModifyTeamError::NoTeam) + } + } + + pub fn toggle_ready(&mut self, client_id: ClientId) -> bool { + let client = &mut self.clients[client_id]; + if let Some(room_id) = client.room_id { + let room = &mut self.rooms[room_id]; + + client.set_is_ready(!client.is_ready()); + if client.is_ready() { + room.ready_players_number += 1; + } else { + room.ready_players_number -= 1; + } + } + client.is_ready() + } + #[inline] pub fn set_var(&mut self, client_id: ClientId, var: ServerVar) -> Result<(), AccessError> { if self.clients[client_id].is_admin() { diff -r abd5eb807166 -r e705d30e0f10 rust/hedgewars-server/src/handlers.rs --- a/rust/hedgewars-server/src/handlers.rs Thu Dec 19 23:13:58 2019 +0300 +++ b/rust/hedgewars-server/src/handlers.rs Sat Dec 21 00:26:17 2019 +0300 @@ -319,12 +319,10 @@ } } HwProtocolMessage::SuperPower => { - let client = server.client_mut(client_id); - if !client.is_admin() { + if server.enable_super_power(client_id) { + response.add(server_chat(SUPER_POWER.to_string()).send_self()) + } else { response.warn(ACCESS_DENIED); - } else { - client.set_has_super_power(true); - response.add(server_chat(SUPER_POWER.to_string()).send_self()) } } HwProtocolMessage::Watch(id) => { diff -r abd5eb807166 -r e705d30e0f10 rust/hedgewars-server/src/handlers/inroom.rs --- a/rust/hedgewars-server/src/handlers/inroom.rs Thu Dec 19 23:13:58 2019 +0300 +++ b/rust/hedgewars-server/src/handlers/inroom.rs Sat Dec 21 00:26:17 2019 +0300 @@ -3,7 +3,8 @@ core::{ room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM}, server::{ - ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, StartGameError, + ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult, ModifyTeamError, + StartGameError, }, types, types::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM}, @@ -174,37 +175,31 @@ } } RoomName(new_name) => { - if is_name_illegal(&new_name) { - response.warn("Illegal room name! A room name must be between 1-40 characters long, must not have a trailing or leading space and must not have any of these characters: $()*+?[]^{|}"); - } else if server.has_room(&new_name) { - response.warn("A room with the same name already exists."); - } else { - let (client, room) = server.client_and_room_mut(client_id, room_id); - if room.is_fixed() || room.master_id != Some(client_id) { - response.warn(ACCESS_DENIED); - } else { - let mut old_name = new_name.clone(); - swap(&mut room.name, &mut old_name); - super::common::get_room_update(Some(old_name), room, Some(&client), response); + use crate::core::server::ModifyRoomNameError; + match server.set_room_name(client_id, room_id, new_name) { + Ok(old_name) => { + let (client, room) = server.client_and_room(client_id, room_id); + super::common::get_room_update(Some(old_name), room, Some(client), response) } + Err(ModifyRoomNameError::AccessDenied) => response.warn(ACCESS_DENIED), + Err(ModifyRoomNameError::InvalidName) => response.warn(ILLEGAL_ROOM_NAME), + Err(ModifyRoomNameError::DuplicateName) => response.warn(ROOM_EXISTS), } } ToggleReady => { - let flags = if client.is_ready() { - room.ready_players_number -= 1; - remove_flags(&[Flags::Ready]) + let flags = if server.toggle_ready(client_id) { + add_flags(&[Flags::Ready]) } else { - room.ready_players_number += 1; - add_flags(&[Flags::Ready]) + remove_flags(&[Flags::Ready]) }; + let (client, room) = server.client_and_room(client_id, room_id); let msg = if client.protocol_number < 38 { LegacyReady(client.is_ready(), vec![client.nick.clone()]) } else { ClientFlags(flags, vec![client.nick.clone()]) }; - response.add(msg.send_all().in_room(room.id)); - client.set_is_ready(!client.is_ready()); + response.add(msg.send_all().in_room(room_id)); if room.is_fixed() && room.ready_players_number == room.players_number { let result = server.start_game(room_id); @@ -307,21 +302,15 @@ } } SetTeamColor(team_name, color) => { - if let Some((owner, team)) = room.find_team_and_owner_mut(|t| t.name == team_name) { - if !client.is_master() { - response.error(NOT_MASTER); - } else { - team.color = color; - response.add( - TeamColor(team.name.clone(), color) - .send_all() - .in_room(room_id) - .but_self(), - ); - server.client_mut(owner).clan = Some(color); - } - } else { - response.warn(NO_TEAM); + match server.set_team_color(client_id, room_id, &team_name, color) { + Ok(()) => response.add( + TeamColor(team_name, color) + .send_all() + .in_room(room_id) + .but_self(), + ), + Err(ModifyTeamError::NoTeam) => response.warn(NO_TEAM), + Err(ModifyTeamError::NotMaster) => response.error(NOT_MASTER), } } Cfg(cfg) => {