Skip to content

Commit

Permalink
Replace unnecessary guild cloning with cheaper alternatives (#1410)
Browse files Browse the repository at this point in the history
Fixes #1409
  • Loading branch information
MelonShooter committed Jun 27, 2021
1 parent 504f5a4 commit fb83066
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 40 deletions.
8 changes: 5 additions & 3 deletions src/framework/standard/help_commands.rs
Expand Up @@ -339,15 +339,17 @@ async fn check_common_behaviour(
return help_options.lacking_permissions;
}

if let Some(guild) = msg.guild(&cache_http).await {
msg.guild_field(&cache_http, |guild| {
if let Some(member) = guild.members.get(&msg.author.id) {
if !has_correct_roles(options, &guild.roles, &member) {
return help_options.lacking_role;
}
}
}

HelpBehaviour::Nothing
HelpBehaviour::Nothing
})
.await
.unwrap_or(HelpBehaviour::Nothing)
}

#[cfg(all(feature = "cache", feature = "http"))]
Expand Down
57 changes: 31 additions & 26 deletions src/framework/standard/mod.rs
Expand Up @@ -260,8 +260,10 @@ impl StandardFramework {
return Some(DispatchError::BlockedGuild);
}

if let Some(guild) = guild_id.to_guild_cached(&ctx.cache).await {
if self.config.blocked_users.contains(&guild.owner_id) {
let owner_id_option = ctx.cache.guild_field(guild_id, |guild| guild.owner_id).await;

if let Some(owner_id) = owner_id_option {
if self.config.blocked_users.contains(&owner_id) {
return Some(DispatchError::BlockedGuild);
}
}
Expand Down Expand Up @@ -835,32 +837,35 @@ pub(crate) async fn has_correct_permissions(
) -> bool {
if options.required_permissions().is_empty() {
true
} else if let Some(guild) = message.guild(&cache).await {
let channel = match guild.channels.get(&message.channel_id) {
Some(channel) => channel,
None => return false,
};
let member = match guild.members.get(&message.author.id) {
Some(member) => member,
None => return false,
};
} else {
message
.guild_field(cache, |guild| {
let channel = match guild.channels.get(&message.channel_id) {
Some(channel) => channel,
None => return false,
};

let perms = match guild.user_permissions_in(channel, member) {
Ok(perms) => perms,
Err(e) => {
tracing::error!(
"Error getting permissions for user {} in channel {}: {}",
member.user.id,
channel.id,
e
);
return false;
},
};
let member = match guild.members.get(&message.author.id) {
Some(member) => member,
None => return false,
};

perms.contains(*options.required_permissions())
} else {
false
match guild.user_permissions_in(channel, member) {
Ok(perms) => perms.contains(*options.required_permissions()),
Err(e) => {
tracing::error!(
"Error getting permissions for user {} in channel {}: {}",
member.user.id,
channel.id,
e
);

false
},
}
})
.await
.unwrap_or(false)
}
}

Expand Down
15 changes: 9 additions & 6 deletions src/model/guild/member.rs
Expand Up @@ -407,12 +407,15 @@ impl Member {
&self,
cache_http: impl CacheHttp + AsRef<Cache>,
) -> Result<Permissions> {
let guild = match cache_http.as_ref().guild(self.guild_id).await {
Some(guild) => guild,
None => return Err(From::from(ModelError::GuildNotFound)),
};

guild.member_permissions(cache_http, self.user.id).await
let perms_opt = cache_http
.as_ref()
.guild_field(self.guild_id, |guild| guild._member_permission_from_member(self))
.await;

match perms_opt {
Some(perms) => Ok(perms),
None => Err(From::from(ModelError::GuildNotFound)),
}
}

/// Removes a [`Role`] from the member, editing its roles in-place if the
Expand Down
16 changes: 11 additions & 5 deletions src/model/guild/mod.rs
Expand Up @@ -1737,23 +1737,29 @@ impl Guild {
return Ok(Permissions::all());
}

let member = self.member(cache_http, &user_id).await?;

Ok(self._member_permission_from_member(&member))
}

/// Helper function that's used for getting a [`Member`]'s permissions.
#[cfg(feature = "cache")]
pub(crate) fn _member_permission_from_member(&self, member: &Member) -> Permissions {
let everyone = match self.roles.get(&RoleId(self.id.0)) {
Some(everyone) => everyone,
None => {
error!("@everyone role ({}) missing in '{}'", self.id, self.name,);

return Ok(Permissions::empty());
return Permissions::empty();
},
};

let member = self.member(cache_http, &user_id).await?;

let mut permissions = everyone.permissions;

for role in &member.roles {
if let Some(role) = self.roles.get(role) {
if role.permissions.contains(Permissions::ADMINISTRATOR) {
return Ok(Permissions::all());
return Permissions::all();
}

permissions |= role.permissions;
Expand All @@ -1762,7 +1768,7 @@ impl Guild {
}
}

Ok(permissions)
permissions
}

/// Moves a member to a specific voice channel.
Expand Down

0 comments on commit fb83066

Please sign in to comment.