From b3aa441c2d61ba324396deaf70f2c5818fd3f528 Mon Sep 17 00:00:00 2001 From: Lakelezz <12222135+Lakelezz@users.noreply.github.com> Date: Sat, 7 Oct 2017 14:34:39 +0200 Subject: Help-commands filtering and Member-prefix-search (#182) --- src/framework/standard/help_commands.rs | 20 ++++++++++---------- src/framework/standard/mod.rs | 21 ++++++++++++--------- src/model/guild/mod.rs | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/framework/standard/help_commands.rs b/src/framework/standard/help_commands.rs index 42527d0..9bae941 100644 --- a/src/framework/standard/help_commands.rs +++ b/src/framework/standard/help_commands.rs @@ -31,6 +31,7 @@ use super::{Args, Command, CommandGroup, CommandOrAlias, CommandError}; use client::Context; use model::{ChannelId, Guild, Member, Message}; use utils::Colour; +use framework::standard::{has_correct_roles, has_correct_permissions}; fn error_embed(channel_id: &ChannelId, input: &str) { let _ = channel_id.send_message(|m| { @@ -50,14 +51,13 @@ fn remove_aliases(cmds: &HashMap) -> HashMap<&String, &I result } -fn right_roles(cmd: &Command, guild: &Guild, member: &Member) -> bool { +/// Checks whether a user is member of required roles +/// and given the required permissions. +fn has_all_requirements(cmd: &Command, guild: &Guild, member: &Member, msg: &Message) -> bool { if cmd.allowed_roles.is_empty() { - true + has_correct_permissions(cmd, msg) } else { - cmd.allowed_roles - .iter() - .flat_map(|r| guild.role_by_name(r)) - .any(|g| member.roles.contains(&g.id)) + has_correct_roles(cmd, guild, member) && has_correct_permissions(cmd, msg) } } @@ -106,7 +106,7 @@ pub fn with_embeds(_: &mut Context, if let Some(member) = guild.members.get(&msg.author.id) { if let Ok(permissions) = member.permissions() { if !permissions.administrator() && - !right_roles(cmd, &guild, member) { + !has_all_requirements(cmd, &guild, member, &msg) { break; } } @@ -213,7 +213,7 @@ pub fn with_embeds(_: &mut Context, if let Some(member) = guild.members.get(&msg.author.id) { if let Ok(permissions) = member.permissions() { if cmd.help_available && - (right_roles(cmd, &guild, member) || + (has_all_requirements(cmd, &guild, member, &msg) || permissions.administrator()) { let _ = write!(desc, "`{}`\n", name); has_commands = true; @@ -279,7 +279,7 @@ pub fn plain(_: &mut Context, if let Some(member) = guild.members.get(&msg.author.id) { if let Ok(permissions) = member.permissions() { if !permissions.administrator() && - !right_roles(cmd, &guild, member) { + !has_all_requirements(cmd, &guild, member, &msg) { break; } } @@ -366,7 +366,7 @@ pub fn plain(_: &mut Context, if let Some(member) = guild.members.get(&msg.author.id) { if let Ok(permissions) = member.permissions() { if cmd.help_available && - (permissions.administrator() || right_roles(cmd, &guild, member)) { + (permissions.administrator() || has_all_requirements(cmd, &guild, member, &msg)) { let _ = write!(group_help, "`{}` ", name); } } diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs index 601c118..7156186 100644 --- a/src/framework/standard/mod.rs +++ b/src/framework/standard/mod.rs @@ -22,7 +22,7 @@ use std::default::Default; use std::sync::Arc; use client::Context; use super::Framework; -use model::{ChannelId, GuildId, Message, UserId}; +use model::{ChannelId, GuildId, Guild, Member, Message, UserId}; use model::permissions::Permissions; use internal::RwLockExt; @@ -514,12 +514,7 @@ impl StandardFramework { if let Some(member) = guild.members.get(&message.author.id) { if let Ok(permissions) = member.permissions() { if !permissions.administrator() { - let right_role = command - .allowed_roles - .iter() - .flat_map(|r| guild.role_by_name(r)) - .any(|g| member.roles.contains(&g.id)); - if !right_role { + if !has_correct_roles(&command, &guild, &member) { return Some(DispatchError::LackingRole); } } @@ -947,7 +942,7 @@ impl Framework for StandardFramework { } #[cfg(feature = "cache")] -pub(crate) fn has_correct_permissions(command: &Arc, message: &Message) -> bool { +pub(crate) fn has_correct_permissions(command: &Command, message: &Message) -> bool { if !command.required_permissions.is_empty() { if let Some(guild) = message.guild() { let perms = guild @@ -958,4 +953,12 @@ pub(crate) fn has_correct_permissions(command: &Arc, message: &Message) } true -} \ No newline at end of file +} + +#[cfg(feature = "cache")] +pub(crate) fn has_correct_roles(cmd: &Command, guild: &Guild, member: &Member) -> bool { + cmd.allowed_roles + .iter() + .flat_map(|r| guild.role_by_name(r)) + .any(|g| member.roles.contains(&g.id)) +} diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index 8173a04..e6023cb 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -741,6 +741,24 @@ impl Guild { }) } + /// Retrieves all [`Member`] that start with a given `String`. + /// + /// If the prefix is "zey", following results are possible: + /// - "zey", "zeyla", "zey mei" + /// But the following are not because case-sensitivity: + /// - "Zey", "ZEYla", "zeY mei" + /// + /// [`Member`]: struct.Member.html + pub fn members_starting_with(&self, prefix: &str) -> Vec<&Member> { + self.members + .values() + .filter(|member| + member.user.read().unwrap().name.starts_with(prefix) + || member.nick.as_ref() + .map_or(false, |nick| + nick.starts_with(prefix))).collect() + } + /// Moves a member to a specific voice channel. /// /// Requires the [Move Members] permission. -- cgit v1.2.3