# HG changeset patch # User alfadur # Date 1572211901 -10800 # Node ID 91f0c5ec37b5b63bd8cb90eb9331c28df72963ad # Parent d668fcb9307ec753b146f472e95c0809a0ebb6ca move change_master into the server diff -r d668fcb9307e -r 91f0c5ec37b5 rust/hedgewars-server/src/core/server.rs --- a/rust/hedgewars-server/src/core/server.rs Sat Oct 26 23:48:57 2019 +0200 +++ b/rust/hedgewars-server/src/core/server.rs Mon Oct 28 00:31:41 2019 +0300 @@ -45,6 +45,20 @@ } #[derive(Debug)] +pub struct ChangeMasterResult { + pub old_master_id: Option, + pub new_master_id: ClientId, +} + +#[derive(Debug)] +pub enum ChangeMasterError { + NoAccess, + AlreadyMaster, + NoClient, + ClientNotInRoom, +} + +#[derive(Debug)] pub struct UninitializedError(); #[derive(Debug)] pub struct AccessError(); @@ -349,6 +363,50 @@ } } + pub fn change_master( + &mut self, + client_id: ClientId, + room_id: RoomId, + new_master_nick: String, + ) -> Result { + let client = &mut self.clients[client_id]; + let room = &mut self.rooms[room_id]; + + if client.is_admin() || room.master_id == Some(client_id) { + let new_master_id = self + .clients + .iter() + .find(|(_, c)| c.nick == new_master_nick) + .map(|(id, _)| id); + + match new_master_id { + Some(new_master_id) if new_master_id == client_id => { + Err(ChangeMasterError::AlreadyMaster) + } + Some(new_master_id) => { + let new_master = &mut self.clients[new_master_id]; + if new_master.room_id == Some(room_id) { + self.clients[new_master_id].set_is_master(true); + let old_master_id = room.master_id; + if let Some(master_id) = old_master_id { + self.clients[master_id].set_is_master(false); + } + room.master_id = Some(new_master_id); + Ok(ChangeMasterResult { + old_master_id, + new_master_id, + }) + } else { + Err(ChangeMasterError::ClientNotInRoom) + } + } + None => Err(ChangeMasterError::NoClient), + } + } else { + Err(ChangeMasterError::NoAccess) + } + } + #[inline] pub fn set_var(&mut self, client_id: ClientId, var: ServerVar) -> Result<(), AccessError> { if self.clients[client_id].is_admin() { diff -r d668fcb9307e -r 91f0c5ec37b5 rust/hedgewars-server/src/handlers/common.rs --- a/rust/hedgewars-server/src/handlers/common.rs Sat Oct 26 23:48:57 2019 +0200 +++ b/rust/hedgewars-server/src/handlers/common.rs Mon Oct 28 00:31:41 2019 +0300 @@ -98,38 +98,6 @@ response.add(rooms_msg.send_self()); } -pub fn change_master( - server: &mut HwServer, - room_id: RoomId, - new_master_id: ClientId, - response: &mut Response, -) { - let room = &mut server.rooms[room_id]; - if let Some(master_id) = room.master_id { - server.clients[master_id].set_is_master(false); - response.add( - ClientFlags( - remove_flags(&[Flags::RoomMaster]), - vec![server.clients[master_id].nick.clone()], - ) - .send_all() - .in_room(room_id), - ) - } - - room.master_id = Some(new_master_id); - server.clients[new_master_id].set_is_master(true); - - response.add( - ClientFlags( - add_flags(&[Flags::RoomMaster]), - vec![server.clients[new_master_id].nick.clone()], - ) - .send_all() - .in_room(room_id), - ); -} - pub fn get_room_join_data<'a, I: Iterator + Clone>( client: &HwClient, room: &HwRoom, diff -r d668fcb9307e -r 91f0c5ec37b5 rust/hedgewars-server/src/handlers/inroom.rs --- a/rust/hedgewars-server/src/handlers/inroom.rs Sat Oct 26 23:48:57 2019 +0200 +++ b/rust/hedgewars-server/src/handlers/inroom.rs Mon Oct 28 00:31:41 2019 +0300 @@ -2,7 +2,7 @@ use crate::{ core::{ room::{HwRoom, RoomFlags, MAX_TEAMS_IN_ROOM}, - server::{HwServer, LeaveRoomResult}, + server::{ChangeMasterError, ChangeMasterResult, HwServer, LeaveRoomResult}, types, types::{ClientId, GameCfg, RoomId, VoteType, Voting, MAX_HEDGEHOGS_PER_TEAM}, }, @@ -315,7 +315,7 @@ .in_room(room_id) .but_self(), ); - server.clients[owner].clan = Some(color); + server.client_mut(owner).clan = Some(color); } } else { response.warn(NO_TEAM); @@ -571,32 +571,47 @@ let mut echo = vec!["/rnd".to_string()]; echo.extend(v.into_iter()); let chat_msg = ChatMsg { - nick: server.clients[client_id].nick.clone(), + nick: server.client(client_id).nick.clone(), msg: echo.join(" "), }; response.add(chat_msg.send_all().in_room(room_id)); response.add(result.send_all().in_room(room_id)); } - Delegate(nick) => { - let delegate_id = server.find_client(&nick).map(|c| (c.id, c.room_id)); - let client = &server.clients[client_id]; - if !(client.is_admin() || client.is_master()) { + Delegate(nick) => match server.change_master(client_id, room_id, nick) { + Ok(ChangeMasterResult { + old_master_id, + new_master_id, + }) => { + if let Some(master_id) = old_master_id { + response.add( + ClientFlags( + remove_flags(&[Flags::RoomMaster]), + vec![server.client(master_id).nick.clone()], + ) + .send_all() + .in_room(room_id), + ); + } + response.add( + ClientFlags( + add_flags(&[Flags::RoomMaster]), + vec![server.client(new_master_id).nick.clone()], + ) + .send_all() + .in_room(room_id), + ); + } + Err(ChangeMasterError::NoAccess) => { response.warn("You're not the room master or a server admin!") - } else { - match delegate_id { - None => response.warn("Player is not online."), - Some((id, _)) if id == client_id => { - response.warn("You're already the room master.") - } - Some((_, id)) if id != Some(room_id) => { - response.warn("The player is not in your room.") - } - Some((id, _)) => { - super::common::change_master(server, room_id, id, response); - } - } + } + Err(ChangeMasterError::AlreadyMaster) => { + response.warn("You're already the room master.") } - } + Err(ChangeMasterError::NoClient) => response.warn("Player is not online."), + Err(ChangeMasterError::ClientNotInRoom) => { + response.warn("The player is not in your room.") + } + }, _ => warn!("Unimplemented!"), } }